EE ——— ee
Solaneviaem iene
=
Computing with the Oric 1
Computing with the Oric 1
lan Hickman
Newnes Technical Books
Newnes Technical Books
is an imprint of the Butterworth Group
which has principal offices in
London, Boston, Durban, Singapore, Sydney, Toronto, Wellington
First published 1984
© Butterworth & Co. (Publishers) Ltd, 1984
Borough Green, Sevenoaks, Kent TN15 8PH, England
All rights reserved. No part of this publication may be reproduced or
transmitted in any form or by any means, including photocopying and
recording, without the written permission of the copyright holder,
application for which should be addressed to the Publishers. Such written
permission must also be obtained before any part of this publication is
stored in a retrieval system of any nature.
This book is sold subject to the Standard Conditions of Sale of Net Books
and may not be re-sold in the UK below the net price given by the
Publishers in their current price list.
British Library Cataloguing in Publication Data
Hickman, lan
Computing with the Oric 1.
1. Oric 1 (Computer)
I. Title
001.64’04 QA76.8.0/
ISBN 0-408-01444-X
Library of Congress Cataloging in Publication Data
Hickman, lan
Computing with the Oric 1.
Includes index.
1. Oric 1 (Computer)—Programming. 2. Basic
(Computer program language) I. Title.
QA76.8.068H53 1984 001.64 83-19426
ISBN 0-408-01444-X
Filmset by Illustrated Arts, Sutton, Surrey.
Printed in England by Whitstable Litho Ltd., Whitstable, Kent.
Preface
When my new Oric 1 was delivered | connected it up, to an
admittedly aged colour TV, and selected one of the spare tuner
buttons. After the TV set had warmed up (valves, you know — I said it
was ancient) there was the standard message that the Oric displays at
switch-on.
Of course, | was just lucky: the spare button happened to be tuned
to channel 36 and needed no more than a slight tweak to give a clear,
steady display. Simple commands and programs ran just as |
expected from previous experience with my old home computer, a
‘first generation’ machine, now much modified. From there on things
soon became a bit more complicated. You see, the Oric is a real
‘second generation’ home computer, with a host of facilities which
make it a very powerful machine, and | was naturally tempted to have
a dabble with these. So | followed that sound old proverb, ‘when all
else fails, refer to the handbook.’
The Oric handbook is a substantial affair which buttonholes you at
the outset with the friendly comment ‘pleased to meet you’ and a
sketch of a whimsical square-faced computer-person. | soon found
that there is a vast amount of information in the handbook, and it’s all
good solid stuff, reflecting the enormous range of facilities available
on the Oric. However, ‘good solid stuff ’ soon becomes indigestible
— it’s too concentrated, like trying to eat an Oxo cube. So my
purpose is to ease your entry to the fascinating world of personal
computing with the Oric. With the aid of a few more ‘vegetables’
(explanations and examples), | hope to turn that cube into a much
more palatable dish of soup!
This book in no sense replaces the comprehensive Oric manual.
Rather, it complements it, filling out the information there presented.
In many instances, what the manual doesn’t say is as important as
what it does say, even more so in some cases. For example, one short
vi Preface
demonstration program in the chapter on colour graphics runs fine as
printed. But then the manual encourages one to experiment by
changing some of the parameters (numbers which define just how the
program is executed), without any warning that the result may be to
‘crash’ the computer! (Full details in Chapter 4.) Don’t worry; a crash
on a computer is not like a car crash — there’s no damage done. It’s
just that the computer sulks and ignores any attempt to control it from
the keyboard. On the Oric you can extricate yourself from minor
crashes at the push of a button (just how is fully explained later), but
sometimes even this won’t work. In these cases, one must disconnect
the power from the computer for a few seconds and then re-apply it.
This works infallibly, but unfortunately the program you had entered
into the computer before the crash will have been effectively
expunged from the Oric’s memory! If you know all this beforehand,
crashes are no more than a wretched nuisance. To the newcomer
however, they are particularly frustrating, especially as he usually has
no idea of the cause.
No undue criticism of the Oric manual is intended here; it is a very
much better handbook than is supplied with many other models. But
computer manuals do tend to be written by people who know all
about computers — we wouldn't want it otherwise — and they don’t
always realise that points which are obvious to them need to be spelt
out in detail for the newcomer to personal computing. They are also
of course, like any other author, subject to limitations of space.
This book, then, is not meant to be read straight through, like a
novel, but rather used as a back-up to the Oric manual, filling out the
background and perhaps explaining things in a little greater detail. It
is for this reason that one or two fundamental concepts — such as
counting in binary notation — are covered more than once, and | do
not feel that the resultant repetition calls for an apology. It is a well-
known characteristic of the learning process that the second time you
meet a topic it seems less daunting and easier to understand, even if
you did not grasp it fully at the first encounter. The reader will find
further information on some of the topics covered in these pages in
my earlier book Get More From Your Personal Computer, also
published by Newnes Technical Books. The first fourteen chapters of
this book have been arranged to cover the same topics as the corres-
ponding chapters in the Oric manual; | hope this arrangement will
prove convenient and simplify matters when cross-referring.
Of course, some order of preference must be observed when using
this book. For example, it would be pointless tackling Chapter 9
(Advanced Graphics) before Chapter 4 (Colour and Graphics); whilst
if you are new to computing, Chapters 1 to 3 should be very high on
your list of priorities. Chapter 14 will not be of much use to you unless
you obtain a printer, while Chapter 13, on machine code, is definitely
Preface vii
advanced stuff, to be postponed until you really know your way
around the machine in BASIC. At that stage you will be ready to tackle
machine code programming, which is both useful and very interest-
ing, and, with the aid of an assembler, not so very much more difficult
than writing BASIC.
My thanks are due to Oric International Ltd for supplying a
machine and an early sample printer, to Tansoft Ltd, for advance
copies of the Oric Owner, and to Durell Software for a copy of their
Oric Assembler/Disassembler. My colleague Mr P. Diamond kindly
read through the manuscript to check for any ‘howlers’ and other
errors. Last but by no means least my thanks are due to my wife for
putting up with some months of domestic disorganisation during
which she saw very little of me, to my children Richard and Jacquie
for helping to run the household whilst | was wielding a pen, and to
Mrs D. M. May who did all the typing.
| dedicate the book to all owners of an Oric 1, and to all potential
owners. | hope that it will prove useful and ease their path to mastery
over the machine.
lH.
OONDUABWH —
Contents
Absolute beginners start here
Setting up the computer
Programming in BASIC
Colour and graphics
Editing and debugging BASIC programs
Arithmetic, algebra and trigonometry
Binary numbers and Boolean logic
Strings and things
Advanced graphics
The Sound of (Oric) Music
Saving programs on tape
Better BASIC
Machine code
Printers and hard copy
Odds and ends
Appendix 1 Oric 1 memory map
Appendix 2 Attributes
‘Appendix 3. ASCII code
Appendix 4 Centronics interface
Appendix 5 Text screen map
Appendix 6 High-resolution screen map
Appendix 7 Oric software suppliers
Index
10
14
26
36
42
51
60
65
75
83
86
94
117
126
134
135
136
138
142
143
144
147
Absolute beginners start
here
If you have never used a computer before, it may seem rather a
daunting and complicated prospect. But remember that mankind has
been computing for a long time. The very word ‘compute’ comes
from the Latin, com meaning with and putare meaning to reckon (an
account). Just reckoning up one’s account — simple addition — was
awkward enough in Roman numerals; just imagine what long
division must have been like! Arabic numerals are much more conve-
nient and most of us can manage simple arithmetic using these.
Nevertheless, when people had to handle a great many sums, they
looked for some way of automating the chore and various aids were
produced.
From abacus to computer
The earliest devices, such as the abacus of Fig. 1.1, were very simple
— but highly effective in the hands of a skilled operator. Later, as man
became more skilled in mechanics, a whole series of mechanical
computing devices were invented; a typical electrically driven model
developed between the wars is illustrated in Fig. 1.2. The MADAS
was more than just an adding machine; it performed Multiplication,
Addition, Division And Subtraction. Such machines reached the
peak of their sophistication in the fifties, but the transistor sounded
their death knell and within a few years desk-top calculators were all
electronic. Meanwhile, during the war, computers were being
developed. These were intended to improve the accuracy of artillery
fire by solving the complicated ballistic equations more rapidly than
could be done by hand. These early computers used valves, so cost,
power consumption, excess heat and reliability were very real
problems and in fact the war finished before they entered service.
2 Absolute beginners start here
ee a pa ye
eh We yee ip Ws PY qt Ly
Fe aot
BRE Poe pe pd
7 2 3 O | 8 9
NUMBER REPRESENTED
Figure 1.1 Chinese abacus (reproduced by courtesy of the Science Museum)
These early computers were designed to solve specific sets of equa-
tions, but it was soon realised that they could be made into more
useful general purpose machines if not only the data itself (e.g. in the
artillery case, muzzle velocity, barrel elevation and azimuth, wind
speed, etc.) but also the program — that is to say the series of opera-
tions which were to be performed upon the data — were fed in by the
operator. Thus, instead of performing a fixed sequence of calcula-
tions designed into the machine once and for all, it could operate
under ‘stored program control’ using whatever program was appro-
priate for the problem at hand.
Absolute beginners start here 3
Figure 1.2 An early electromechanical calculator, the fully automatic electric
calculating machine ‘MADAS’ (reproduced by courtesy of the Science Museum)
During the fifties computers were being successfully developed
and in the sixties they were in widespread use. They were powerful,
but large and very expensive. With the development of integrated cir-
cuits during the sixties, the large ‘mainframe’ computers became ever
more powerful. But for smaller applications (and budgets) it was now
possible to produce a ‘minicomputer’ in a desk-top cabinet which
was as powerful as the earlier ones of the mainframe models.
Integrated circuit development led to more and more circuitry being
packed into each single small device package, so we had medium
scale integration (MSI) and then large scale integration (LSI).
At this stage (the early seventies) it became possible to produce a
complete four-function calculator (add, subtract, multiply and
divide) in a package fitting comfortably in the palm of your hand.
These calculators, like their mechanical predecessors, could only
execute a single function at a time; to add two numbers, each had to
be keyed in separately and the add key pushed. To multiply the result
by a third number, one had to push the multiply key and enter the
number, and so on. To work out the same calculation again with
other numbers meant carrying out the whole procedure again with
the new numbers.
For longer calculations, a programmable calculator is very handy.
Here, one carries out the calculation once with the first set of
numbers and the calculator, in addition to supplying the answer,
memorises the sequence of operations. To repeat the sum on another
set of numbers, it is only necessary to key them in; the calculator does
the rest. The most expensive and sophisticated programmable
calculators now available can do almost anything with numbers that
a personal computer can do. But there the similarity ends!
The minicomputers mentioned earlier became more powerful with
the advances made in LSI, but they remained too expensive for
private ownership. However, as a result of the same advances, it
became possible to produce a small computer that the individual
could afford. The first personal computers appeared in America in the
second half of the seventies and soon proved very popular. The
4 Absolute beginners start here
British market for home computers burst into life shortly after and is
now the largest in Europe. UK-produced machines have been popu-
lar from the beginning and they now compete very successfully in
world markets. Successive models have introduced more new
features and the computing power now available for little more than
£100 exceeds that of machines costing many tens of thousands of
pounds only a decade or two ago. The hallmark of these machines is
versatility; they are much more than programmable calculators. For
instance they handle words, which they can sort into alphabetical
order, use as labels for information, print out on paper (given a
suitable electronic printer), as well as displaying them on a TV set.
They can generate and display complicated patterns and pictures,
animated as well as static, in full colour on a standard colour TV. And
they can generate sounds, musical and otherwise, to accompany
video games or for other purposes.
The Oric 1
One of the most remarkable machines to hit the market recently is the
Oric 1 (Fig. 1.3). Like the great majority of personal computers, this is
programmed in an English-like language called BASIC, which is very
easy to learn. Each make of personal computer has its own version of
BASIC, but all versions are very similar, the Oric version containing
Figure 1.3 The Oric 1
Absolute beginners start here 5
virtually all of the commands found on any of the other models. The
Oric colour graphics facilities are outstanding, permitting very
detailed and varied colour displays on a colour TV or on a special
colour monitor, which gives even clearer and more detailed pictures.
Alternatively a black and white TV or monitor can be used, of course.
The Oric also has an exceptional ability to generate sounds, with a
built-in loudspeaker. Alternatively, there is a sound signal output for
connection to a hi-fi or music centre. In addition to random noise
effects, the Oric 1 can play solo tunes, or provide two- or three-part
harmony.
This book should help you to get the best out of your Oric 1
personal computer, at whatever level you wish to operate it. If the
colour graphics are what excites you, then Chapter 4 will help you to
master the Oric’s colour display, with further information on
advanced graphics in Chapter 9. If you want to try your hand at com-
posing computer music, then Chapter 10 will assist you.
However, you are unlikely to be satisfied for long with blindly key-
ing in the programs from the Oric manual or from this book: you will
want to modify the programs or write completely fresh ones of your
own. This is where Chapter 3 will help and once you have mastered it
you will be in a position to write your own programs. Chapter 12
deals with the finer points of programming and will become very use-
ful to you in due course. If you wish to do any computational pro-
gramming — number crunching — you may need to brush up your
maths; here, Chapters 6 and 7 will help you. You will certainly want
to save your better programming efforts on cassette for later re-use,
and Chapter 11 augments the instructions in the Oric manual with
further useful hints and tips.
As far as possible, the chapters of this book have been arranged to
parallel those of the Oric manual, so that (for example) programming
in BASIC is dealt with in Chapter 3 in both. With the aid of the manual
and this book, you should soon become proficient in home comput-
ing, be it purely for pleasure or with a more serious specific end in
view. You do not have to treat this as a textbook to be dutifully
ploughed through from cover to cover. Follow up first the topics that
interest you most and come to the others when you are ready for
them. For example, you may be content with programming in BASIC
for quite a long time — or even indefinitely. In this case, Chapter 13
on machine code programming can be left till much later or ignored
entirely. On the other hand, later on, when your mastery of the
machine in BASIC has given you the necessary confidence, you may
want to tackle the challenge of machine code, which is, so to speak,
the computer’s native tongue. It is not really that much more difficult
than BASIC and for certain purposes has very real advantages, as
Chapter 13 explains.
6 Absolute beginners start here
Some computer terms explained
Before coming to all these different topics though, and to round off
this introductory chapter, let’s introduce some of the jargon. | won’t
apologise for its existence; a few moments talking to a car enthusiast
or a weekend sailor will show that any specialised interest generates
its own jargon. In computerese, many of the ‘buzz words’ are in fact
acronyms — words made from a set of initials. It may help you to
remember what they mean if you know how they arose in the first
place.
ROM means Read Only Memory. It contains a fixed pattern of
information in the form of ‘bits’, and just what they are we will come to
inamoment. The bits stored in ROM can either be instructions which
the computer follows in carrying out its work, or data, for example
the shape of thewarious letters and symbols that are displayed on the
screen of the monitor. (The monitor is the Visual Display Unit (VDU)
via which a personal computer communicates with the operator.
Special purpose monitor VDUs are available, but usually a TV set is
used.) Thus to the computer, ROM is a cross between a dictionary
and a book of standing orders. Such books of reference are for read-
ing from, not writing in — hence the name ROM. The contents are
fixed when the ROM IC (integrated circuit) is manufactured; they are
not ‘forgotten’ when the computer is switched off.
RAM, on the other hand, is more like an exercise book or jotter.
The computer can store information in Random Access Memory, for
later re-use. Perhaps a blackboard is a better analogy, as old informa-
tion can be rubbed out and the space re-used to store new data. The
RAM ICs used in most personal computers ‘forget’ their contents
when the computer is switched off. But why Random Access? Like so
many other terms, it reflects old history.
Since the earliest days of computers there have been two main
classes of memory: fast access memory with strictly limited capacity;
and slow access memory, or backing store, with a much larger
capacity. The latter has always used magnetic recording, as ona tape
recorder. A computer would use either tape, disc or drum type
recorders. Tape on large spools provides enormous storage Capacity
for data but obviously if you need access to data stored at random
places along the tape, it is very slow. (It helps if you, or more precisely
the computer, knows roughly where the data is, as fast forward or
rewind can be used to get there more quickly.) But frequently used
data needs to be available virtually instantly, in a few millionths of a
second. Disc or drum is faster than tape, as one can move the read/
write head across the surface as with a gramophone pick-up lowering
device which enables you to select any track on the LP at will. How-
ever, even when that is done and the right part of the selected track
Absolute beginners start here 7
comes round, we are still talking of access times of milliseconds rather
than microseconds.
In the early days of computing, fast access memory technology
was always a limiting factor and various schemes were in use. In
some, a block of data bits was shot serially into a coil of lightly
suspended wire or a column of mercury in a tube, in the form of
pulses of sound. As, one after the other, the pulses came out of the
other end (somewhat distorted by their passage) they were tidied up
and shot in again. They thus provided a recirculating memory, but
bits in this stream of ‘serial data’ could only be read or changed
(‘written’) as they popped out of the end of the acoustic delay line.
What was needed was a really fast memory, where any bit at random
could be accessed at any random time, without having to wait for a
specific time slot when the data bit came round.
Early random access memories used various technologies but
nowadays special RAM ICs are always used. These have a large
planar array of storage cells (large in number, but microscopic in size)
with circuitry to access any one of these at random, hence the name
RAM. The data to be read out from or written into a given cell appears
on a data line. To select which cell is read from or written to, a
number representing the ‘address’ of that cell is notified to the RAM
on a group of wires which are known as the ‘address bus’. In fact
there are eight storage cells associated with each address and con-
sequently eight data lines, called (you've guessed!) the ‘data bus’.
The data may be used by the computer to represent almost anything,
depending on how the program is organised, but it actually takes the
form, at this stage, of a number in the range 0 to 255. If 255 seems a
funny sort of number, this is only because we are used to counting in
tens. This brings us back to the topic of those ‘bits’ we mentioned
earlier, so now let's take a look at them and see why computers are so
fond of them.
We must start off by thinking about the way we normally count, in
tens. There are ten decimal digits, namely 0 to 9 inclusive. Decimal
simply means ‘in tens’, from the Latin decem, ten. Our word digit,
like the French word doigt, comes from the Latin digitus — a finger;
that’s how man has counted through the ages, on his fingers.
Computers of course run on electricity, and it would be possible
with modern technology to make a computer that counted in tens.
The output of one circuit would be either 0,1,2,3 volts etc., up to 9
volts. If the count then increased by 1, instead of switching to 10 volts
it would return to O volts but increment another counter by one in the
process, just like putting a 1 in the tens column in simple arithmetic.
Such a computer would have some advantages, but it would be com-
plicated and expensive even with up-to-date technology. When
computer development started, it would have been quite impracti-
8 Absolute beginners start here
cal. All valves, including those used in the earliest computers, start
wearing out as soon as they are used. The resistors in the circuits
changed their value slightly with temperature and as they aged. These
and other such limitations meant that ten different voltage levels in a
circuit would have been quite impractical; the 5 volt level for
example might finish up nearer 4 or 6 volts. What was possible, how-
ever, was a simple on/off circuit, representing O or 1. Imagine a series
of lamps: each one is either on or off. Never mind if one bulb is a bit
brighter than another, one battery a bit newer than another; it’s either
ON or OFF , a binary decision. But how do we count in binary, with
only two digits — 0 and 1? In decimal, to indicate one more than 9 we
put a 1 in the tens column and go back to 0 in the units column. In
binary, instead of units, tens and hundreds columns, etc., we have
units, twos and fours columns, etc. (see Fig. 1.4). Put one hand
w
i)
i
a
=
ONODOPWNHeH O
100
127
128
255
256
Figure 1.4 Some decimal numbers and their binary equivalents
rFoooooooodcoedcoedceo0cocoeoaocaoaoaaaaaaaaaded
ot ie OOO oo ooo ono no non ono Romo Romo monomomonomomo)
or orrrqoooooocoocooeoooooeoo0o0o°o
SOorFOoOrFOoOCOOrFCOOCOOOrF RF eEF Ee EFF Fr OOOO OCOCCOO aw
OrorrOoOrFrFOOOrFKF KF RF OOO ORFRKF FF OOOO Ff
OororOoOrFOrFOrFOOrFrF OOF FPF OOR KF OOrFRKFK OO BRD
Oororrrr OOCCOCOCCOOOCOCCOOOCOCOOOCOCOCCO
OororooOoOrFrFrFR rR FY OO OOCCOOCOCOCCOCOOCOCOCCCO
0
1
0
1
0
1
0
1
0
1
0
1
0
1
0
1
0
1
1
0
1
0
1
0
1
0
1
0
Absolute beginners start here 9
behind your back and use only your thumb on the other — now try
counting on it. Nought is OK, thumb down: one is simple, thumb up.
For the next number, you will have to put a 1 in the twos column and
thumb down.
Rather confusingly, we have to call the twos and fours columns,
etc. in binary by decimal names because we just don’t have any
binary names corresponding to tens, hundreds, etc. We do have a
collective name for binary numbers, though; they are called ‘bits’
short for BInary digiTS. Now ten tens may be a hundred, but the fact is
that the largest number you can express with two decimal digits is 99,
i.e. (9 X 10) + 9. Similarly, the largest number you can express with
two binary digits is (1 X 2) + 1, or decimal 3, written as 11 in binary.
Home computers work with groups of eight bits, called bytes. The
largest number you can express with one byte is 11111111, that is to
say a 1 in the 128s column, plus a1 in the 64s column ... plus a1 in
the ones column — and so we have 255. You can see that writing
large numbers in binary produces long strings of 1s and Os. A more
compact way of writing them, called hexadecimal (or hex for short) is
described in the first part of Chapter 7.
Of course, a computer can handle much larger numbers and also
fractional and negative numbers, but to represent each of these it has
to use several bytes, turning them back into decimal numbers for our
benefit when displaying them on the screen. The result is that we
don’t need to worry about bits or bytes in order to use a computer,
any more than you need to know how the internal combustion
engine works to drive a car. However, if you do understand the
engine it may make you a better driver and it also makes driving more
interesting. In the same way, we shall find later that we can do more
interesting things with Oric’s colour graphics display if we know a
little about bits and bytes.
We shall meet some more computer jargon in later chapters, but
let’s deal with that as we come to it.
Setting up the computer
The Oric handbook tells you how to connect the power supply to the
computer and the computer to a TV set. The lead supplied for the TV
connection has a phono plug at one end to plug into the phono
socket on the back of the Oric which provides the UHF TV output
signal. The other end is fitted with the ubiquitous Belling Lee coaxial
plug, to plug into the TV set’s antenna or aerial socket, if the com-
puter is delivered in the UK. For use abroad, a different plug is often
necessary. The TV output signal is factory-set to VHF TV channel 36
and the instructions with the TV set should tell you how to tune it.
When correctly tuned in, the display should look as shown in the
Oric handbook, except that in place of
X BYTES FREE
you will see
47870 BYTES FREE
ona 48 K model, or
15104 BYTES FREE
on the 16 K model.
A byte is the unit of information storage used in (most) personal
computers and may be considered as a pigeon hole. One of these
can store a letter or other printable character or (within limits) a
number. But don’t worry about that now, it is covered in more detail
later. The other thing you will notice is that the printing appears as
black on a white background, as illustrated in the handbook, except
that on most TV sets the white background does not extend as far as
10
Setting up the computer 11
the edges of the screen. Indeed, in the dark area around the
background, to the top right, appears the word CAPS which indicates
that the keyboard will only type capital letters whether or not one of
the SHIFT keys is pressed. Again, the reason for this is covered later.
Setting up the display
The display will be black printing on a white ground on either a black
and white or a colour TV. However, in the latter case some fine tun-
ing and adjustments of the brilliance, colour and contrast controls
may be necessary to minimise any distracting stray colouring around
the printed characters. This can occur due to two main causes. The
first is a limitation due to the clever way the colour TV signal is packed
into a format originally designed for a black and white picture; the
black and white picture obviously contains less information. It is the
same effect as the flashes of false colour often seen in a TV picture
when someone is wearing a striped tie or a herring bone suit. The
other cause is a basic limitation of the actual colour TV screen. This
consists of thousands of groups of three coloured dots; red, green
and blue. In the white background area they are all equally illumi-
nated, but at the edges of the black lettering the last row of dots illumi-
nated will usually all be of one particular colour. There are also other
causes that can contribute to the effect.
The screen of a black and white TV is continuous, not made up of
individual dots, and in all probability you will find you get a clearer
picture on a good quality black and white set, though results with a
cheap portable set may be disappointing. If you plan to use your
computer as a business aid, for stock control, ledger accounts, etc.,
then a black and white set may be best for your application, espe-
cially as any printout you produce will also be in black and white —
unless you go to the considerable expense of a colour printer. Use of
the various different colours won’t give you colour of course, but you
will still get different gradations of brightness — a scale of greys from
black to white.
Most people, however, will want to use a colour TV to take advan-
tage of the Oric’s extensive colour facilities. You will find that the
black printing on a white ground (which is automatically selected at
switch on) gives better clarity than white on a black background. Try
it: just type
INK 7: PAPER 0
and then press the key labelled RETURN. You will probably find the
false colour effects mentioned earlier are more obtrusive. If so, yeu
12 Setting up the computer
can return to the original black on white by typing
INK 0: PAPER 7
followed by pressing RETURN, as always.
Best results will be obtained by not setting the contrast and colour
controls too high — the same settings as for a normal TV programme
will usually prove satisfactory. If the display shows ghosting, i.e. the
last letter in a row repeated faintly one or more times, adjusting the TV
set’s fine tuning may help, but there is another dodge you can try.
Remember the red, green and blue dots of which the screen is com-
posed? In a white area they are all lit up and in a black area none is,
leading to the coloured edges to letters already mentioned. See if you
get a clearer display by typing
INK 3: PAPER 1
(don’t forget to press RETURN).
INK 3 sets the lettering to yellow and PAPER 1 sets the background
to red (just why, and why you need a colon, is explained in later
chapters). The improved clarity results because there is far less differ-
ence between the TV signal for red and that for yellow than there is
between the signals for black and for white. With yellow on red, none
of the blue dots are illuminated, a// of the red dots are illuminated over
the entire area (background and printing) and, only where there is
printing, the green dots are also lit. You can see this quite clearly by
looking closely at the display; yes, unlike as in painting, on a TV
screen red and green make yellow.
The Oric handbook says, when discussing the use of the socket for
the cassette recorder, that almost any make will do — cheap port-
ables are better than expensive hi-fi models. The reason for this is
that, almost without exception, cheap portables employ an automa-
tic recording level circuit, whereas with a hi-fi model you will have to
experiment to find the right setting of the recording level. However,
once found and noted, a hi-fi machine should prove perfectly suit-
able, even if it is ‘overkill’ for this particular purpose. Nevertheless, if
a cheap recorder is adequate, cheap cassettes may very well prove
inadequate, a point covered in more detail in the chapter on saving
programs on tape.
The reset button
Occasionally, when you write a program it may not do what you
expect it to, especially if you have not formulated clearly and
Setting up the computer 13
precisely how and in what order you expect it to operate in order to
achieve your desired objective. When there is such a flaw in the basic
logic of a program, it can ‘get lost’ when you put it into operation and
then you may find that the keyboard has no effect — you are ‘locked
out’ from control of the machine. The first thing to try is to type C
whilst holding down the key marked CTRL (short for CONTROL).
This is referred to as CONTROL C and will often return control to the
keyboard, but not always. In these cases, pressing the RESET button
will almost always return control to the keyboard.
If you are new to computing, the reference in the Oric handbook to
a ‘warm start’ may mystify you; the term comes from the arrangement
found on some other personal computers. On these, pressing the
RESET button prompts the machine to offer you the choice of a ‘cold
start’ or a ‘warm start’. A cold start clears the machine’s memory
entirely, i.e. it has the same effect as switching the machine on from
cold. Thus all the RAM (random access memory, that is those pigeon
holes we mentioned earlier where one can store a number or a letter,
etc.) is effectively wiped clean, for it does not retain information when
switched off. A warm start, on the other hand, resets the area of RAM
which the machine uses to make notes of things it needs to remember
as it goes along (since if this gets corrupted the machine ‘gets lost’),
without clearing the area of RAM holding the program.
On the Oric, the RESET button does not offer one the choice of a
warm or cold start, but automatically performs a warm start. If a cold
start is necessary, it may be achieved by removing the power supply
plug from the back of the Oric and then replacing it. Just occasionally
this may prove necessary, if the RESET button (which is rather incon-
veniently located underneath the machine on the left-hand side) fails
to restore control to the user. An alternative method of prompting a
cold start is given in a later chapter.
Programming in BASIC
Chapter 3 of the Oric 1 manual covers most of the BASIC commands
and statements available in the Oric dialect of BASIC. It also gives
practical examples, both in ‘immediate’ mode (also called
‘command’ or ‘calculator’ mode) and in ‘program’ mode (sometimes
called ‘file’ mode). Note that a computer runs a program whereas at a
concert you buy a programme. This useful distinction does not exist
in American English.
In immediate mode, if you type:
PRINT 5 + 2
the computer will execute the command immediately, once only,
and then ‘forget’ it completely, as soon as you press the RETURN key.
(The term RETURN is short for ‘carriage return’, the carriage in ques-
tion carrying the print head mechanism ofa Teletype machine, which
was at one time the normal ‘user interface’ by which one communi-
cated with a computer.) In the program or file mode, on the other
hand, our instructions to the computer are not executed immedi-
ately, but are stored for later use. Thus, again quoting an example
from the Oric handbook, we might have the following four-line
program:
10 CLS
20 PRINT ‘ENTER YOUR NAME”
30 INPUT N$
40 PRINT ‘PLEASED TO MEET YOU, ”’; N$
Each line is typed in exactly as it appears above, followed by pressing
RETURN. Until the key labelled RETURN is pressed, the line is only
14
Programming in BASIC 15
stored in that part of the computer’s memory which holds data being
displayed on the screen. Pressing RETURN enters the program line
into that part of the computer’s memory devoted to storing programs.
Pressing RETURN also returns the cursor (a blinking square which
indicates where the next character to be typed in will appear) to the
left-hand side of the display, on the next line down. If there is no next
line, i.e. the present line is at the bottom of the display, the cursor will
still be moved to the left of the bottom line, but only after all of the
lines currently appearing on the screen have been shifted up one line.
The top line will thus be lost from the display, but (if it is a program
line) not from the computer's program memory area.
Numeric and string variables
As the Oric handbook explains, a group of one or more characters (of
which the first must be a letter) is used to name a ‘variable’. Anumeric
variable is simply a number; we call it a variable because it may take
different values at different times, as in the statement PRINT 2*Y. (The
computer uses * for a multiplication sign to avoid confusion with the
letter X.) If we have previously set Y = 2.5 (or the computer has
worked out Y for itself from some previous sum) then
PRINT 2*Y
will result in the display
5
whereas if the current value of Y were 99, then we would get 198.
Oric handles positive or negative numbers in the range 107 °° to 1078
(approximately).
There is another sort of variable, called a string. This is quite simply
a list of any printable characters (including letters, numbers, punctua-
tion, spaces) enclosed by literals, i.e inverted commas (quotes.) A
string variable name must end with a $ sign. Thus
A$= “A1 $*(@)E”
PRINT A$
will print the string
Al $*(@)£
16 Programming in BASIC
The only way the computer knows whether a line is a program line
to be stored in the program file or a command to be executed
immediately is by the first character (ignoring spaces) that it meets
when it scans the line after you press RETURN. If the first character is a
number, the line will be treated as a program line, if not it will be
executed immediately. To expand a little on the handbook’s com-
ments, try
PRINT ABCDEF
You will get:
0
? SYNTAX ERROR
This is because Oric interpreted the (apparent) six-letter variable
name (of which it can only distinguish the first two) as ABC, followed
by the reserved BASIC keyword DEF. Names of either numeric or
string variables must not contain any BASIC keyword. (The BASIC
command DEF is covered later.) PRINT ABCDFE is acceptable
though, and will return the value 0 unless this variable has previously
been set to some other value; BASIC assumes an initial value of zero
for any numeric variable unless told otherwise.
Try
ABCDFE = PI
PRINT ABCDFE
Yes, Oric knows the value of 7. Now try
PRINT PIPIPI
This will print out PI three times, but this is a special case in that Oric
recognises PI as an entity. We set the variable ABCDFE to PI earlier,
but
PRINT ABCDFEABCDFE
will only print out Pl once unless we separate the variables with a
semicolon or comma. Thus:
PRINT ABCDFE; ABCDFE
will give
Programming in BASIC 17
3.14159265 3.14159265
with one space in between, or four spaces if we used a comma.
Try
M$ = “ABC”; N$ = “DEF”
PRINT M$;N$
You will see that, in the case of string variables, a semicolon results in
no space in between. A comma results in three spaces. All very con-
fusing, isn’t it? But never mind if you can’t remember it now. You will
soon get used to it when you start writing your own programs:
remember the old Chinese proverb!
There are lots of titbits of BASIC programming knowledge which
you will pick up in time; in fact there are usually two or more ways of
doing any given job. Just as an example, let’s refer back to the four-
line ‘ENTER YOUR NAME’ program, mentioned earlier. The CLS in
line 10 clears the screen and places the cursor at the top left-hand
corner. But
10 ? CHR$(12)
would do equally well, though it is slightly longer.
On the other hand, the INPUT command can be used to call up a
message on the screen, preceding the question mark which it always
prints. This also produces a nicer display, for the version in the Oric
manual, when run, looks like this:
ENTER YOUR NAME
2
You then enter your name following the question mark. However,
the following version:
10 CLS
30 INPUT ““WHAT IS YOUR NAME” ;N$
40 PRINT “PLEASED TO MEET YOU, ”;N$
produces
WHAT IS YOUR NAME?
This version of the program is also more compact, as a bonus!
(Note the space before the closing inverted commas in line 40.)
18 Programming in BASIC
Call random
number K
From K
calculate
random address,
L
Let X =
content
of address L
Call random
number M
Place a
blank at L
Figure 3.1 Flow diagram for the ‘Snowstorm’ program
Programming in BASIC 19
Some program examples
But it is best to pick up this sort of knowledge ‘on the job’, by practice.
Otherwise you would be overwhelmed by a mass of detail. Instead,
I'll finish the chapter with one or two program examples, some of
which are slightly longer than those given in the Oric Handbook.
First, here is ‘Snowstorm’, Figure 3.2. This program uses the TEXT
mode in conjunction with Oric’s PLOT and SCRN commands —
these are covered in the next chapter. The program starts by clearing
the screen to a black background and then it ‘snows’. The multiplica-
tion sign ‘*’ is used to represent a snowflake. Figure 3.1 is a flow
diagram which should help to explain the program’s method of
operation. The initialisation calls up white printing on a black
background and clears the screen: program lines 25 and 26. Next a
random location X, Y on the screen is calculated, line 30. Next we
use the SCRN command to look at that location to see if there is
already a snowflake there, line 40: we have come to a lozenge, a
decision box. In line 40, 32 is the ASCII code for a blank space (see
Appendix 3). If the location does not hold a snowflake — the YES out-
put of the box — then we print one.
10 REM "“SNOWSTORM"
20 REM FOR ORIC I
25 INK7:PAPERO:CLS: T=50
26 REM INITIALIZATION
30 X=SQKRND (1) 2 Y=Z6XxXRND C1)
35 REM SETS UP RANDOM ADDRESS
40 IF SCRN(X,Y)=32 THEN PLOT X,Y,"*" ELSE GOSUB1000
45 REM IF NO SNOWFLAKE THERE, PRINTS ONE
46 WAIT T
47 REM DELAY: T SETS RATE OF SNOWFALL
50 GOTO 30
1000 M=RND (1)
1005 REM CALLS A RANDOM NUMBER
1010 IF Mé.8 THEN 1040
1020 REM DECIDE WHETHER TO MELT SNOWFLAKE
1030 PLOT X,Y," "
1040 RETURN
Figure 3.2 ‘Snowstorm’ program
However, if there is a snowflake there already, we make a random
choice as to whether to leave it there or ‘melt’ it by printing a space in
that position instead. We do this by calling another random number,
let’s call it M, and seeing whether it is less than .8. If so, we leave the
snowflake there; otherwise we thaw it by plotting a blank at that
location.
Whichever of the three possibilities occurred, they all lead to a
delay box which sets the rate at which it snows. After the chosen
20
Define
variable
array
2
Clear flag
and
variables
3
Draw current
state of
board
Figure 3.3 ‘Noughts and Crosses’ flow diagram
Print
win/draw
message
7
Another
game?
Programming in BASIC
Programming in BASIC 21
delay, the program returns to the second operation following START.
An interesting point about a program written to implement this flow
diagram, is that it will have no END; it will continue to snow indefi-
nitely, or until we deliberately interrupt it. Before too long, the initially
blank screen will fill up until roughly 80 per cent of the positions show
a snowflake. After that, the old snowflakes are thawing as fast as the
new ones fall.
The problem of working out the precise average percentage of
snowflakes on the screen is left as an exercise for the reader.
Now a longer program and one which, unlike ‘Snowstorm’, uses
only commands which are likely to be found on any personal com-
3 REM NOUGHTS AND CROSSES
6 REM FOR ORIC I
10 DIMV$(3,3)
20 FORI=1T03:FORJ=1TO3
30 V(I,J)=" “sNEXT: NEXT
40 P=0
SO FOR I1=1T016:FRINTs: NEXT
60 PRINTSPC(16) sV®(1, 1) 5 "TI" 3 V8(1,2)3
79 PRINT" II"; V#(1,3)
80 GOSUB340
99 PRINTSPC (16) sV#(2, 1) 5 "ITI"3V8(2,2) 3
100 PRINT"II"3V$(2,3)
110 GOSUB340
120 PRINTSPC (16) sV$(3, 1) p"TI"3V$(3,2) 3
130 PRINT"II"3;V$(3,3)
140 PRINT: PRINT: PRINTSPRINTS PRINT: PHP +4
150 IF INT(P/2)=F/2THENO=0
160 IF INT(P/2)<>P/2THENO=1
170 DATAL,1,1,251,352,1,2, 2,2, 5, 351,35
180 DATAL, 1,251,351 y by 2p 2524 3e 25155, 2,:
190 DATA1,1,2,2,3,3,1,3,2,2, 5,1
200 R=0 .
210 FORC=1TO8: Z=0: FORD=1T03: READE, F
220 Z=Z+ASC (V$(E,F)) sNEXT: IFZ=237THENR=1
230 IFZ=264THENR=2
240 NEXT:RESTORE
250 IFR=1THENL$="NOUGHT": GOTO290
260 IFR=2THENL$="CROSS": GOTO290
270 IFP< >1OTHENGOTO320
280 L%=""A DRAW "
290 PRINT:PRINT"WELL DONE "yL%;" ANOTHER GAME";: INFUT" "sF%
300 IFASC (FS) =B9THEN2ZO
31 END
320 GOSUB350
330 GOTOSO
340 PRINTSPC (16) 3 "IITIIIII": RETURN
350 IFQ=OTHENAS$="NOUGHT ": B&="0"
360 IFQ=1THENAS$="CROSS": BS="X"
370 PRINT: PRINTAS;"’s go,enter row and column"
380 PRINT"e.g. 2,2= centre square"
390 INPUT" "3I,J
400 IFV$(1I,J)=" "“THEN420
410 PRINT"NO GO, already occupied":GOTO350
420 IFQ=OTHENV$ (I,J) ="0"s RETURN
430 IFQ=1THENV$(1I,J)="X"s RETURN
Figure 3.4 ‘Noughts and Crosses’ program
22 Programming in BASIC
puter. This program, ‘Noughts and Crosses’ (Figure 3.4), should thus
prove entirely portable (suitable for any machine), provided that the
version of BASIC on that machine includes string array facilities. The
game is for two players, not one player versus the machine. As it is
portable, it cannot write direct to the screen in random positions
using POKE, PRINT AT or PLOT, so how can we add another nought
or across to a display that is already there? The answer is quite simple:
we must store the display in the main RAM memory area, not the
VDU RAM. Then, when we have modified the display to include the
current ‘go’, we simply rewrite the whole display on the screen from
scratch. It would be foolish to undertake a program of this size with-
out having a clear idea of the tactics it employs, so we must draw a
flow diagram first, as in Figure 3.3.
In addition to drawing the board we need to keep track of the
various noughts and crosses entered on it and a convenient way of
doing this is with an array. We also need a tally of the number of turns
so that the program knows whose turn it is and when a draw occurs
— we will call this tally a ‘flag’. So the first activity after START is to
define our variable array — ‘variable’ because what gets entered in it
is different for each game. At the start of each game this will need
‘initialising’, i.e. setting to all blanks. It is a good idea to do this as a
separate action, as it gives us a Convenient point to come back to if, at
the end of a game, the answer to the ANOTHER GAME? message is
YES.
Now we can draw the board and update the flag to indicate that we
are processing turn number one, and any other flags we may find we
need can also be updated. At this point we check to see if there is a
winning line and if there is, print an end of game message. Of course
there won't be a winning line until at least five goes have been
entered, but this arrangement results in quite a neat flow diagram,
though several other arrangements would work equally well. The
next step is to check for a draw, i.e. nine turns entered and no win-
ning line. If there is no winning line and no draw either we can go to
the ‘input next turn’ routine, which includes a trap and error message
for attempts to go in an already occupied square. When a valid turn
has been entered we return to the ‘draw board’ routine, and now of
course the board will show the turn just entered.
When running, the program simply circles round the various loops
until another game is not required. As can be seen, the flow diagram
is quite a modest affair, but to implement each of the boxes will,
typically, take several lines of program. In fact the boxes on the flow
diagram have been numbered so that the program (Figure 3.4) can
indicate which lines correspond to each box, as explained in the
following paragraphs.
Line 10. This corresponds to box 1. It defines a string array; that is
Programming in BASIC 23
to say, each of the terms of the variable array could be set to any string
of characters enclosed within literals, e.g. “ABC123?=—” or what-
ever. We shall only use single character strings, namely“, “O”’ or
ay ae
Lines 20 to 40. These clear the flag (P is a flag telling us how many
goes have been made) and the variable field — the string array — by
setting P to zero and all the positions on the board to blanks. A blank
of course is simply a space enclosed by inverted commas, or literals,
thus “’ ’’. | is the first subscript, used to denote the row, and J the
second, denoting the column. The two FOR NEXT loops on lines 20
and 30 are ‘nested’; the BASIC interpreter knows automatically that
the first NEXT refers to J and completes that loop before incrementing
| on meeting the second NEXT for the first time. In this way we rapidly
set all the squares to blanks ready to print the board for the first time.
Lines 50 to 130. These correspond to box three and draw the
board using only BASIC PRINT routines. By printing 16 blank lines,
line 50 ensures the screen is empty. Line 60 prints 16 spaces to centre
the display nicely and the three spaces on the top row of the board,
separated by bars.
Line 80 prints a row of seven capital ‘I’s, to divide the top from the
middle line of the board. As we are going to need to do this again, it is
written as a subroutine call to line 340. On completion, line 340
automatically RETURNs execution to the line following that which
called it — in this case, to line 90.
Lines 90 to 130 print the rest of the board in similar fashion.
Lines 140 to 160 correspond to box 4. P is incremented by one and
tested to see whether it is odd or even, the result being stored as the
condition of flag Q. On the first pass, P will be set to 1 and hence Q to
1 also. As Q = 1 is later defined as ‘X’s go’, X, i.e. a cross, always
starts.
Lines 170 to 260 correspond to decision box 5. Lines 170 to 190
list the eight possible ways of winning. Thus line 170 starts 1,1 1,2
1,3, which represents the top row, and the other rows, columns and
diagonals follow.
Line 200 sets the winning line flag R to 0 (a previous game may have
left it at 1 or 2) and the next four lines test each row, column and
diagonal in turn to see whether nought or cross has a winning line of
three. Remember that ASC(I$) returns the numerical value in decimal
notation of the first character in 1$, where I$ signifies any string vari-
able. Thus ASC(““AND’’) = 65 because 65 is the ASCII code for A.
Here, I$ is V$(E,F) and hence, depending on E and F and the state of
the game, I$ will be either a blank (32 in ASCII), an O (capital O, not 0
nought) which is 79 in ASCII, or an X which is 88 in ASCII.
Hence if there is a winning line of noughts, R will be set to 1, or to 2
for a winning line of Xs, but will be left at O otherwise. In the event of a
24 Programming in BASIC
10 REM TRIG TEST
20 REM FOR ORIC I
30 CLS:PRINT:PRINT: INK1
35 PRINTCHR$ (4) ; CHR$ (27)
40 PRINT"N TRIG TEST" :PRINT
45 PRINTCHR$ (4)
SO PRINT" FOR ORIC I"“sPRINT
60 PRINT"Reply to (say) SIN A equals?"
65 PRINT"With a/c etc. ":sPRINT
70 PRINT"and to (say) a/b equals?"
80 PRINT“with TAN A etc. ":FPRNT
90 DIM V(18)
100 V$(1)="a/co"2V$(2)="b/co"s VBC) =" a/b"
110 V$(4)="Cc/a"sV$(S) ="C/b"tV$(6) ="b/a"
120 V$(7)="SIN A": V$(8)="COS A": V$(9)="TAN A"
130 V®(10)="COSEC A":V$(11)="SEC A":V$(12)="COT A"
140 V$(13)="a/co"3 V$(14) ="b/co":V$(15) ="a/b"
150 V$(16)="c/a":V$(17) ="C/b":V$(18) ="b/a"
155 PRINT:PRINT"Keyboard is in typewriter mode, "
156 PRINT:PRINT"press SHIFT for CAPITALS."
157 WAIT120:PING
160 PRINT: PRINT"PRESS ANY KEY TO CONTINUE"
170 IFKEY$=""THENGOTO170
180 Z=0: T=1: INKO
1990 PRINTCHR$ (20)
200 HIRES
210 I[=I+1: IF I=7THENI=1
215 PAFPER7-I
220 CURSET40,150,1
230 DRAW120,0, 1: DRAWO, -99, 1: DRAW-120,99,1
240 CURSET64, 138, 0: CHAR46S,0,1
250 CURSET162, 100,0:CHAR97,0,1
260 CURSET100, 152, 0: CHAR98, 0,1
270 CURSET100, 88,0: CHAR99,0, 1
280 CURSET150, 150, 1: DRAWO,-10, 1: DRAWLO,90,1
FORF=1TO12
READX,Y
CURSETX+56, Y+139,1
NEXT
DATAGL Og Le Lede 2p 2a Bee 4g 2a Fe 34 Ge Sa 7g Be By Be Ae Sel, 3,11
RESTORE
K=INT(11*RND(1)+1.5)
FPRINTSFC (10) 5 V$(K) 32: INFUT" equals";Ds
IFD$=V$ (K +6) THENSOO
PRINT"No, correct answer is "“3V(k+6) :EXPLODE
WAIT 200
Z=2-1:1F2.0 THEN Z=0
GOTO200
PRINTSFC (15) "CORRECT": FING: Z=Z+1t
WAIT1IS0O
IF Z=12 THEN6OO
GOTO200
FRINT"Well done, you really know those now!"
FORE=1TOS
FING: WAITSO
NEXT
FRINTCHRS (20)
WAITSOO
1000 TEXT:LIST
Figure 3.5 ‘Trig Test’ program
Programming in BASIC 25
win, line 250 or 260 directs the program to the PRINT WIN/DRAW
message, line 290. Otherwise, we exit from box 5 via NO to box 8.
Line 300 forms decision box 7, a YES returning us to box 2, aNO to
END.
Line 270 is box 8, which checks that the game is to continue. NO if
P is 10, i.e. all goes used up, takes us to box 6 via line 280 picking up
the ‘A DRAW’ message on the way. YES takes us to line 320, which
calls the ‘enter next turn’ subroutine at line 350.
Lines 350 to 390 constitute box 9 and ask for the position of the
next turn in terms of row and column — having already decided on
the basis of flag Q whose turn it is. Position is reckoned from ROW 1
at the top and COLUMN 1 at the left.
Line 400 is decision box 10 leading to line 410 (box 11) in the event
of an invalid entry, i.e. a place already taken.
Lines 420 and 430 are part of box 10, representing the YES exit
from the decision. This loops us back to the ‘draw board’ routine (box
3) without resetting variables and flags: thus the updated state of the
board is drawn and checked for a win or a draw again.
One other point of interest: what happens if an invalid row or
column address is entered? In that case, if one or other of the two sub-
scripts is out of range, negative, or larger than 3, the normal Microsoft
BASIC routine error checking will flag up an OUT OF BOUNDS
error, as V$ is defined in line 10 as DIM V$ (3,3). But note that
V$(3,3) is actually a four by four array as O is a valid subscript. V$(2,2)
would be a three by three array, but V$(3,3) is used as it is more
convenient to talk about the first, second or third row or column; the
seven unused array elements with a 0 in the subscript are simply
ignored. If entered, they would be rejected by line 400 as they have
not been initialised to“ ’’ in lines 20 and 30, and remain at the value
0 allocated to all elements in the array by line 10.
Now a program, ‘Trig Test’ (Figure 3.5), which makes use of both
the sound and the high-resolution graphics facilities of Oric. This
means that if you wish to puzzle out how the program works, you will
have to come back to it after reading Chapters 4, 9 and 10. Even then,
you will be on your own, as there is no line-by-line explanation such
as there was with ‘Noughts and Crosses’, nor even a flowchart to help
you on your way!
Colour and graphics
The Oric manual contains the information you need to select each of
the four different screen modes: TEXT, LORES 0, LORES 1 and
HIRES. The TEXT mode, with black printing on a white ground, is
automatically set up at switch-on and if you switch to another screen
mode you can return to TEXT mode by various ways at any time, as
we shall see later.
Choosing colours
We saw earlier that the colour used for printing (called FORE-
GROUND or INK) and the colour used for BACKGROUND (or
PAPER) can both be changed, and that a different combination may
actually give you a clearer display than the standard black on white
(INK 0 on PAPER 7) called up at switch-on. On my colour TV set, red
on yellow or vice versa are equally effective. Try this short program to
see which you prefer:
10 CLS: LIST
20 WAIT 150
30 INK1: PAPER 3
40 WAIT 150
50 INK 3: PAPER 1
60 WAIT 150
70 GOTO 30
When RUN, this program will switch the printing on the screen
back and forth between red on yellow and vice versa. The eye is
much more sensitive to a red/yellow contrast than to, say, red/
26
Colozr and graphics 27
magenta or blue/cyan. You can easily add, say, lines 42 and 44 as
follows, to compare the results with the standard black on white:
42 INK 0: PAPER 7
44 WAIT 150
Who knows? On your set black on white may give the clearest
display.
Up to now we have been speaking of INK and FOREGROUND as
though they meant the same thing; similarly with PAPER and
BACKGROUND. However, we shall see shortly that this is an over-
simplification. INK and PAPER are ‘global’ commands; they set the
foreground and background colours respectively for the whole
display. Once set, they apply till changed, even if you clear screen
(CLS) or change display mode. However, in the graphics modes we
can set the foreground and background colours locally for each line
or even within a line.
The TEXT mode
Before considering how to use them, let’s define what the four
different modes are for. TEXT is mainly for printing, for example when
writing or editing programs, or entering commands in the immediate
mode such as
INK1: PAPER3 or CONTROL L
(this means typing L while holding down the CONTROL key, labelled
CTRL. It has the effect of clearing the screen and you should get into
the habit of doing this first, every time you LIST a program.)
Each program line or immediate command must, as we have seen,
be followed by a RETURN, which will enter the line in the program
file or execute the command. It will also return the cursor to the start
of the next line down, after first scrolling all the text up one line if the
screen is already full. This action is automatic and affects everything
appearing on the PAPER background area, but not the CAPS
reminder which is to the right, just above the paper.
In CAPS (capitals) mode, the two shift keys only provide access to
those shifted characters which actually appear on the keyboard, e.g.!
above 1, @ above 2, inverted commas (also called quotes or literals)
above comma, etc. Lower case letters are accessed by CTRL T, after
which the keyboard works like a normal typewriter with key ‘A’
returning ‘a’ unless one of the two SHIFT keys is pressed. A second
28 Colour and graphics
CTRL T will return the keyboard to its normal mode. Note that lower
case letters can only be used within quotes, as in:
PRINT ‘‘The quick brown fox etc.’”
Commands must be in upper case; list, run, etc. just won’t work.
However you can, for example, type LIST in typewriter mode with a
shift key held down and this will work.
You can also use the PLOT command (covered below) in TEXT
mode, but remember that, once plotted, any text or background
colour which you have carefully placed at a certain point on the
screen will be subject to the normal screen scrolling action. It will thus
scroll up on the next PRINT after any text reaches the bottom of the
screen.
The LORES 0 mode
LORES 0 is mainly useful where you want to be able to place text (and
perhaps a few graphics symbols) at various places on the screen, for
example in a computer noughts and crosses game. Both of the LOw
RESolution modes cause the automatic selection of black as the
background colour, and INK7 (white) as the foreground colour. You
can then select a different foreground colour and any text or graphic
symbols will be printed in that colour, on black.
The Oric manual explains how to print graphics (i.e. ‘alternate
characters’) in LORES 0 mode. It is easier to see just what the sample
program to illustrate this, ‘ALT. CHARS IN LORES 0’, is doing if you
add a line: 55 WAIT 10.
In LORES 0 you can also specify a background (PAPER) colour
other than black. This colour will then appear as a background in the
extreme left-hand character space in each row. If you change the INK
(foreground) colour, either before or after changing the background,
the paper colour will appear in the next leftmost column as well and
also as background to any text printed (but not PLOTted) on any row,
as far as the end of the text. The rest of the row and the whole of any
row without any text will be blank, except the two leftmost character
spaces already mentioned. The following program illustrates this:
5 REMLORESO, DEMO 1
10 CLS: LORESO
20 WAIT150
30 PAPER1
40 WAIT150
50 INK4
60 WAIT150
Colour and graphics 29
70 PLOT10,10,’“HELLO”
80 WAIT150 : PRINT: PRINT: PRINT: INK3
90 PRINT’‘HELLO”
100 WAIT250
110 CLS
120 INKO: PAPER7
130 LIST
You can however change background colour within a row, as the
next program demonstrates:
5 REMLORESO, DEMO 2
10 LORESO
20 FORI=1TO5
30 READ X
40 PLOT 10 + I, 10, X
50 NEXT
60 DATA 65, 17, 66, 18, 67
70 PLOT 16, 10, 68
65, 66 and 67 are the ASCII codes for A, B and C respectively (see
Appendix D of the Oric manual), while 17, 18, being less than 32, are
not ASCII codes. Codes 0-31 are used as control codes or ‘attributes’
(see Appendix C of the Oric manual).
So when this program is run it will print A in white on a black
ground at screen position 11,10, since white on black is automati-
cally called up by LORESO. In the next square along the line, it will
print a block of red background colour and this colour will apply until
changed. In the next square a white B will appear on a red ground.
The next square will show green background (control code 18)
followed by a white C on a green ground. In the next square, line 70
will print a white D, also on a green ground. However, change line 70
to 70 PLOT 17, 10, 68 and the D will appear on a black background.
So, therefore, once set a background colour applies only as long as
consecutive spaces in the row have something plotted in them. If you
want the white D plotted at 17, 10 to appear on a green ground, then
adding PLOT 16, 10, 32 will do the trick — 32 is the ASCII code for a
blank space. Alternatively, either PLOT 16, 10, 18 (set background to
green) or PLOT 16, 10, 7 (set foreground to white) will do equally
well. Either fulfils the requirement of plotting something in the space;
they simply reiterate the existing background or foreground colour
respectively.
As a further example, here is a more interesting version of the Oric
manual’s ‘LORES COLOUR PLOTTING’.
30 Colour and graphics
10 REM*NEW LORES COLOUR PLOTTING*
20 LORESO
30 STP = 2*PI/50
40 R=10: X=10: Y= 10
50 REPEAT
60 REPEAT
70 REPEAT
80 E=17+RND (1) *7
90 PLOT X + R*SIN(C), Y + R*COS(C),E
100 PLOT 37, 10,E
110 C = C+ STP
120 UNTIL C>2*PI
130C =0:X=X+2:Y=Y+1
140 UNTIL Y >15
150 X = 10: Y= 10
160 UNTIL KEY$<>””
170 CLS: LIST
This program nicely illustrates how REPEAT — UNTIL loops can be
‘nested’ one inside another. But after pressing any key the machine
may take a long time to jump out of the circle drawing routine, as it
only looks to see if a key has been pressed after it finishes drawing the
bottom circle. The background colour variable E can take any value
from 17 (red) to 23 (white), so why does the program plot some
squares in black? Try adding a line
105 WAIT 150
and see if you can work out what is happening. Here’s a clue: the
PLOT command automatically takes the integral part of the X and Y
coordinates in line 90, so the ‘black’ squares just never get plotted.
This is a good example of how a program may work well enough, but
not in exactly the way you expect. You can lose the black squares by
changing line 30 to 30 STP = 2*P1/63.
The LORES1 mode
In LORES1, the background must be black; if you select LORES1,
and then change the background, you will find you are back in
LORESO mode. Even if you type PAPERO (which should set the
background to its present value, i.e. black) you will change to
LORESO and the graphics characters will turn back to letters. In the
manual’s ‘MONSTER’ LORES1 demonstration program, note that in
lines 45 and 50, the inverted commas should enclose two blank
spaces. If you would like a monster corpse at the end of each line, just
to prove what a good shot you are, add
Colour and graphics 31
57 PLOT 36,D,A$: PLOT 36,D + 1,B$
In the ‘USE OF SCRN(X,Y)’ program, you will find the display
clearer if you use PAPERG in line 110; note also that the literals in line
200 enclose one ‘blank’, i.e. one press of the space bar. With the
program as it stands, the bombs never actually reach the battleship,
which makes the explosion rather pointless, so try changing line 130
to
130: PLOT N,25,“+”
and line 220 to
220: UNTIL SCRN(A,P) = 43
This actually illustrates an important point about FOR-NEXT
loops. Each time the line 170 to 210 loop is executed, P is incre-
mented. You might think that each time round the loop, the BASIC
interpreter checks P to see if it equals 24, does the loop for the last
time and then goes on to line 220. But that’s not how it works. Each
time it reaches line 210, the machine increments P and then checks to
see if it is greater than 24. Thus we arrive at line 220 with P set to 24 +
1. This way of doing it allows the FOR—-NEXT loop to cope with lazy
programmers who don’t watch their limits. Thus
FORI=0TO 4 STEP 2: PRINT “*”;: NEXT
and
FORI=0TO5 STEP 2: PRINT “*”;: NEXT
will both print three asterisks; indeed the final limit could just as well
be 5.999999. If it is 6, then you will get four asterisks.
The HIRES mode
The Oric’s Hlgh RESolution graphics are great fun and the manual
includes several programs to demonstrate them. Particularly striking
is ‘MOIRE’. Moiré is the French name given to silks figured by the
process called ‘watering’, which leaves faint wavy lines impressed on
the body of the fabric. In optics, moiré fringes are interference
patterns caused by rays from closely spaced point-sources of light; a
similar effect is observed when looking through two thicknesses of net
curtain. The ‘MOIRE’ program results in such fringes when nearly
32 Colour and graphics
parallel white lines are drawn on a black ground. It would be nice to
have the display in colour and you can add a line to the program in
the manual thus: 15 INK1. If you run the amended program, you will
see why the original sticks to the white on black format automatically
called up by the command HIRES.
Our next program ‘MOIRE COLOURS’, is a rewrite of the program
which avoids using the two left-hand columns. In white on black
these are available for use, but with any other colour combination
they are used to store background and foreground colour.
10 REM *MOIRE COLOURS*
20 CLS
30 PRINT ‘‘TYPE 1 FOR RED, 2 GREEN, 3 YELLOW”: PRINT: WAIT 100
40 PRINT “4 BLUE, 5 MAGENTA, 6 CYAN, 7 WHITE”: PRINT: WAIT 100
50 PRINT “8 TO RETURN TO TEXT MODE”: PRINT
60 INPUT “WHICH” ;1
70 IF 1 =8 THEN TEXT: LIST
80 HIRES
90 INKI
100 FORA=0TO1
110 FOR B = 12 TO 239 STEP 6
120 CURSET 12,199*A,1
130 DRAW B — 12, 199 — 398*A,1
140 CURSET 239, 199*A,1
150 DRAW 12- B, 199 — 398*A,1
160 NEXT: NEXT
170 WAIT 200
180 RUN
You can easily modify the program further to give a background
other than black: try changing line 90 to INK1:PAPER3. From there, it
is but a small step to modify the program so that the background
colour is also chosen before running, just like the foreground colour.
In the ‘USE OF SCRN(X, Y)’ program, we saw how to find out what
character is printed in any given square. The corresponding facility in
HIRES for testing any given pixel is POINT(X,Y), though of course a
pixel cannot store a character, it is simply in foreground or
background colour. The command POINT(X, Y) will return the value
zero if the point X,Y is in background colour and —1 if it is in fore-
ground colour. The following lines added to ‘MOIRE COLOURS’
illustrate its use.
90 INK1: PAPER3
165 GOTO 200
200 A = RND(1): B = RND(1)
210 A = INT (A*239): B = INT(B*199)
220 IF POINT(A,B) = 0 THEN T = T + 1: CURSETA,B,1
230 GOTO 200
Colour and graphics 33
When you run the program you may think at first that nothing is
happening — but go and have a cup of coffee. When you come back,
you may notice the picture looks a bit spotty, as though it has
measles. After half an hour, the pattern is still distinctly visible though
very blurred. It would be hours or possibly days before all the
background pixels were turned into foreground colour, but you can
stop the program at any time with CONTROL C. Then ?T: WAIT 300
will tell you how many pixels the program has changed from yellow
to red since it started. CONT (continue) will carry on again from
there.
The ‘LACE CIRCLES’ program in the Oric manual does not use the
two left-hand columns, so INK and PAPER can be used to add fore-
ground and background colours to this with no problems at all.
Watch out for the HIRES program illustrating the FILL command. If
you change line 30 to FILL 2,1,X the machine will still go round the N
loop 200 times and will thus try and FILL 400 lines. The result will be
to colour the three text lines at the bottom of the screen, as the Oric
does not check to see if the program will overrun the bottom of the
HIRES screen. FILL 9,1,X will prevent the program running at all and
a much larger number will cause a crash. So keep the number of lines
within bounds; FILL 2,1,X is acceptable if in line 10 you have FOR N
= 0 TO 99. There are only 40 cells per row, so FILL 1,99,X, for
example, is unacceptable to the machine, but it won’t cause a crash,
as the entry is trapped by an ‘ILLEGAL QUANTITY ERROR IN 30’
error message when the program is run.
Double-height and flashing characters
And now a warning about the program to illustrate double-height and
flashing characters. This one could get you going for hours. Any rows
which display flashing characters (whether double or single height)
are automatically displayed with a black background. The character
appears in the selected foreground colour (INK) for about a quarter of
a second and then is replaced by the background colour for another
quarter of a second and so on. If the penny still hasn’t dropped, add
line
5 INK1
and all will be well. (At switch-on, Oric selects INKO PAPER7...
flashing black characters don’t stand out too well on a black
background!)
This sample program seems to be the only place in the manual that
mentions the ESCape routine, and it mentions it in passing as though
34 Colour and graphics
you naturally know all about it. | didn’t; my old computer doesn’t
have an ESC key — but the handbook for my Epson printer lists its
version of the ASCII codes from 0 to 127. (The full ASCII set is repro-
duced in this book as Appendix 3.) Sure enough, the printer hand-
book gives 27 as the ESCape code and explains that when this is
followed by another specific character, neither is printed; they act
together as a control code. Thus line 20 of the program could be
written in several other ways:
20 PRINT CHR$(4); CHR$(27); “’N’’; ‘DOUBLE FLASH CHARACTERS”’
or
20 PRINT CHR$(4); CHR$(27); CHR$(78); ‘DOUBLE FLASH
CHARACTERS”
or
20 PRINT CHR$(4); CHR$(27); CHR$(X); ‘(DOUBLE FLASH
CHARACTERS”
78 is the ASCII code for N. Why CHR$(xX) in the last version? It won’t
run correctly as it stands, but you might, in the course of writing a
longer program, want to choose, under program control, whether
the characters flash or not. In this case, as a result of an IF — THEN —
ELSE test, you could set X equal to 78 for flashing or 74 (ASCII J) for
steady.
ESCape can be used directly from the keyboard, using the ESCape
key. Thus ESC Q (the keys pressed sequentially, not together as with
the CTRL key) will set the background colour to red for the rest of the
row. However, it will also cause a syntax error message when
RETURN is next pressed. Be careful if you experiment with ESC plus
other keys — some of them will crash the computer.
Note the difference between control letters with ESC and control
letters with CTRL. ESC L (single height flashing standard characters)
might appear in a program line as PRINT CHR$(27); CHR$(76),
whereas CTRL L (clear screen, return cursor to top left) would appear
in a program line as PRINT CHR$(12). This is because, for the CTRL
functions, the letters are reckoned A = 1, B = 2, etc., rather than by
their ASCII values.
Summary
To finish the chapter, here is a summary of the four screen modes:
Colour and graphics 35
1 TEXT
Entry: Automatic at switch on
From LORES 0 or 1
From keyboard, CTRL L
From program, CLS
From HIRES
From keyboard or program, TEXT
Exit: From keyboard or program, LORESO or LORES1 or HIRES as
required.
2 LORESO
Entry: From keyboard or program, LORESO
Exit: To TEXT
From keyboard, CTRL L
From program, CLS
Note: in both LORES modes, on encountering a PRINT
instruction (either from keyboard or program) when the cursor
is at the bottom of the screen, the normal scrolling action will
take place. Thus the screen will gradually revert to TEXT
mode, from the bottom upwards.
To LORES1
From keyboard or program, LORES1
To HIRES
From keyboard or program, HIRES
3 LORES1
Entry: From keyboard or program, LORES1
Exit: To TEXT
From keyboard, CTRL L
From program, CLS
To LORESO
From keyboard or program, LORESO
Note: in both LORES modes, INK7 PAPERO, i.e. white on
black background, is automatically selected. In LORESO
either may subsequently be changed, but in LORES1, only
INK may be changed. If the background is changed, the
screen reverts to LORESO mode.
To HIRES
From keyboard or program, HIRES
4 HIRES
Entry: From keyboard or program, HIRES
Exit: From keyboard or program, TEXT, LORESO or LORES1 as
required.
Editing and debugging
BASIC programs
When | first started using the Oric 1 | was disappointed with the
editing facilities. | was used to a machine whose DELete not only
erased the character under the cursor and stepped the cursor one
place to the left, but also shunted the rest of the line following the
cursor left one character to fill the gap. Similarly SHIFT DELete moved
all characters on that program line (which could be longer than one
display line, as on the Oric) from the cursor onwards, right one space,
giving an INSert function. There was even a command to shift all
program lines from the cursor down a line, so that an additional line
could be entered in the appropriate place on the screen. A useful
refinement, even though a subsequent LIST would sort lines entered
out of order.
Editing with the Oric
The Oric’s editing facilities are not quite that versatile, but they are
quite effective once you have mastered them. The main difficulty is
that, as the handbook points out, what actually gets entered into
program memory when you press RETURN after editing a line is not
necessarily the same as what appears on the screen. In particular, you
should make sure you are thoroughly familiar with the ‘COPYING’
example in the Oric manual. You are? ... Good, then we can look at
some more advanced editing.
For instance, suppose you have a program line
80 WAIT 150: PRINT: PRINT: PRINT: INK3
and you decide you want the program to do something after the
WAIT 150 but before the PRINT statements. Even though you
36
Editing and debugging BASIC programs 37
perhaps shouldn’t have written such a long line to start with, you can
split it into two as follows. Using the appropriate cursor keys, move
the cursor to the extreme left of line 80. Press CTRL and hold it down.
Press A and hold it down till the cursor starts stepping right; release it
when it reaches the colon to the right of 150. (All the keys on the Oric
keyboard ‘auto repeat’ if held down.) Release CTRL and press
RETURN, but do not clear the screen or LIST at this stage. The cursor
will now be on the next line down. Type 85 and then use the cursor
keys — and {¢ to position the cursor over the P of the first PRINT.
Now hold down CTRL and A until the cursor has auto repeated past
INK3, release CTRL A and press RETURN. The 85 you entered as the
tine number will have over written the next line’s line number, but this
is only on the screen, not in program memory. Press CTRL L and LIST
and you will find all is well.
Note that after the first stage, you had entered line 80 as 80 WAIT
150 in program memory. The rest of the line was then stored only on
the screen. This is why you should not clear the screen or LIST at that
stage or you will have to retype the rest of the line after entering 85.
So that is how to split a line: condensing two into one is also quite
simple. Suppose you wanted to make one line of
250 DRAW 29* SIN(F), 29* COS(F),1
260 CURSET 200,140,3
Position the cursor to the left of line 250, press CTRL and auto repeat
A past the end of the line. Release CTRL A and type a colon: this is
always necessary to separate two commands in a program line. Now
use cursor key | and <to position the cursor over the C of CURSET,
and CTRL A to the end of that line — simple.
As always, just to make sure, clear the screen and LIST. You will
find you have
250 DRAW 29* SIN(F), 29* COS(F), 1: CURSET 200,140,3
260 CURSET 200, 140,3
You can now either enter 260 RETURN to remove the redundant line
260 or re-use the number for one or more additional commands,
while still keeping your line numbers advancing nicely in tens.
The points to remember are:
(a) CTRL A will copy the character under the cursor into the program
line.
(b) Any printable character typed (letter, figure, sign, space or punc-
tuation) will also be entered.
38 Editing and debugging BASIC programs
(c) The cursor controls will move the cursor without entering either
the character it was on or the character it steps on to.
These provide the clue as to how to insert or delete within a line.
Deletion is very simple: suppose on checking your listing you spot a
surplus A<32 in line 130 thus:
130 A= RND(1)*128 + 1: IF A>23 AND A<32 A<32 THEN 130
Just CTRL A all the way along the line until the cursor is on the last A.
Now, with >, position the cursor on the T and then CTRL A to the
end of the line. If you overshoot the A and the cursor lands on the <,
press DELete and then continue as above.
Insertion is just a little more tricky, but still quicker than retyping the
whole of a complicated line. Thus suppose you noticed (perhaps as
the result of ‘SYNTAX ERROR IN LINE 250’ when first running the
program) that a bracket was missing:
250 DRAW 29* SIN(F,29* COS(F),1
CTRL A along the line until the cursor is on the first comma. You have
thus entered the line up to and including the first F, so you can now
cursor < one space, type in the missing bracket and then CTRL A to
the end of the line. This will now read
250 DRAW 29*SIN(), 29*COS(F),1
but lo and behold, when you LIST the program it does indeed read
250 DRAW 29*SIN(F), 29*COS(F),1
Sometimes an insertion is even simpler. Thus you may have
entered 90? ““HELLO”’, but when LISTed this will appear as 90
PRINT“ HELLO” with a space after the line number. If in the course of
editing you have to change the line number to 100 it can be typed
straight in and the rest of the line copied with CTRL A. The second 0 of
100 will fit in the gap that LIST always leaves after the line number. A
subsequent LIST will add a new gap in the appropriate place.
If you want a longer insertion, it is easier to do it on the next line
down, thus:
20 PRINT CHR$(4); CHR$(27); ““N CHARACTERS”
J
DOUBLE FLASH
Editing and debugging BASIC programs 39
Control A to the C of CHARACTERS, cursor | to the next line, make
the insertion, cursor back to the C and then CTRL A to the end of the
line. It doesn’t matter if the insertion overwrites the next line down,
but it may be easier to see what you are doing if you clear the screen
and then type LIST 20. This will list just the line to be amended. Or
you could LIST — 20. This will list all the lines up to 20.
In general, one can use LIST M—N to list all the lines between line
M and line N inclusive. M and N need not actually appear as line
numbers. Thus, if all line numbers in a program advanced in tens,
then LIST 95 — 205 would list lines 100 to 200 inclusive.
Before leaving the topic of writing and editing programs, a word
about using the Oric’s keyboard. You will probably find it easier, if
you can’t type, simply to use the forefinger of the right hand (or of the
left hand if you are a ‘southpaw’). This is slow but not too bad once
you are used to finding the keys you want. Rather better is the
‘reporter’s’ method of typing, using both forefingers — you will have
to use both hands anyway when using the CTRL or SHIFT keys.
It is a great pity that Oric does not have a proper typewriter-style
keyboard — such a powerful machine certainly deserves it. If you can
type properly already, that’s a great advantage, but if you can’t it’s
hardly worth trying to learn on the Oric keyboard. If the machine
proves as popular as the manufacturer hopes, it will not be long
before an enterprising company markets an add-on proper
keyboard, just as has happened with other popular home computers.
In the meantime, we have to make do with the Oric’s tiny keys. If like
me you can touch type (or nearly so) you will find the key bleep quite
useful, as it warns you instantly by its absence when you haven't
pushed a key right down or by its double chirp if you get a double
entry due to key bounce. However, if you can’t stand the sound,
CRTL F will turn it off; another CTRL F will turn it on again.
Debugging
While editing is fairly straightforward, debugging is not so easy to pin
down, as the number of different possible problems is almost limit-
less. However, it is worth pointing out that a FOR—NEXT loop should
not be used where REPEAT—UNTIL is more appropriate.
As an example, here is a horrid program:
5 REM HORRID PROGRAM
10 FOR | = 80 TO 90
20 FOR J = 70 TO 100
30 PRINT J;
40 IF J = | THEN PRINT: GOTO 60
40 Editing and debugging BASIC programs
50 NEXT
60 WAIT 100: NEXT
At first sight it looks all right; after all FOR-NEXT loops can be nested,
as in:
100 FORM =1TO 10
110 FORN = 1TO 10
120 PRINT N;
130 NEXT
140 PRINT.
150 NEXT
where each NEXT automatically refers to the loop last entered. If you
enter the HORRID PROGRAM you will find that it runs properly. One
might expect it to print the numbers 70 to 80 on one line, 70 to 81 on
the next and so on, but it doesn’t. The reason is that on encountering J
= 80 in line 40 it goes to line 60 and encounters a NEXT. Not being as
bright as you or me (or perhaps just being more logical) it assumes the
NEXT still applies to J. Hence it proceeds to increment J instead of |
and continues on to J = 100 before (as it thinks) encountering the
second NEXT for the first time. The moral? ... There are several:
(a) Don’t be lazy; NEXT may do but NEXT | (or whatever) is safer.
(b) Be very careful about jumping out of FOR—NEXT loops. The loop
counter J will be left set at what it was when you jumped out. It will be
reset to 70 if you re-enter the loop at line 20, but not if you jump back
in with a GOTO line 30 for example.
(c) Clearly, in this example the J loop should have been executed with
a REPEAT—UNTIL structure, even though as we have seen, Oric
BASIC is very forgiving!
Debugging programs is really something you can only learn by
experience, though there are some useful techniques as we shall see
in a minute. However, one little point is worth mentioning, as it can
catch you out several times before you get used to it. If you find that
the display no longer accepts entries from the keyboard, that the
cursor seems to flit around capriciously without printing, or even
disappears altogether, check that you haven't finished up with INK
and PAPER the same colour. Type INKO: PAPER7 carefully, followed
by RETURN.
If this doesn’t restore normal print control to the keyboard, you will
have to RESET. If even that doesn’t work, you will have to ‘cold start’
by switching off and on again, just accepting the loss of your
program. So if you’ve just written a smashing new program and are
itching to run it, don’t. At least, not until you have first CSAVEd it on
Editing and debugging BASIC programs 41
cassette, as described in Chapter 11. Then you can run it; if it causes
an irrecoverable crash you may be disappointed but not nearly as
annoyed as if you hadn’t saved it first!
Oric has a TRace ON, TRace OFF facility (TRON/TROFF) which is
very useful when debugging a program. Its use is covered in the
manual, so! won't discuss it further here, except to say that it needs to
be used with discretion. For instance, it often doesn’t help much to
have it enabled during a loop such as FOR — NEXT or REPEAT —
UNTIL, since the screen will rapidly fill up with line numbers,
promptly scrolling straight off the screen some printing that the
program was meant to display! In this case (assuming your line
numbers advance in tens) it is better to add some WAIT lines, thus:
15 WAIT 100
25 WAIT 100
35 WAIT 100
These will enable you to see just what is happening and whereabouts
the program goes wrong. If the program produces little screen
printout, TRON and TROFF may be the answer. Another very effec-
tive ploy, when a program hangs up or goes into an infinite loop that
has to be interrupted with CTRL C, is to use a STOP instruction. This
can be popped in at, say,
35 STOP
and the program RUN. The appearance of the Ready message
indicates that all lines up to 30 have executed correctly. The STOP
command can then be renumbered as line 45, the program re-run
and so on. At some point, say line 245 STOP, you won't get a Ready
message, so line 240 is where things go wrong.
Arithmetic, algebra
and trigonometry
Up till now we have only considered programming in BASIC, and it
has been assumed that everyone was acquainted with such simple
arithmetic and algebra as cropped up in the course of the programs.
In this chapter we take a brief look at the three topics in the chapter
heading, since familiarity with these is really an essential prerequisite
to using Oric’s facilities fully.
| hope that the following treatment is comprehensive enough to
enable you to understand the mathematical facilities and functions in
BASIC, but it will certainly have to be brief as this is not a maths
textbook but one about a microcomputer. Consequently, the rules
and results are simply stated, not proved, and fancy titles (e.g.
Commutative Law) dropped in favour of simple examples (e.g. 2 X 3
= 3 X 2). Likewise, as well as purely mathematical considerations,
notes are included to show how a microcomputer handles these
topics.
Arithmetic
There are five kinds of numbers:
(1) Whole or fractional. For example: whole 365, 7; fractional 3/5 or
0.6, 21/3. Whole numbers are called integers. Fractional numbers
larger than 1 are called improper fractions.
(2) Positive or negative. For example: positive + 10, +3.6; negative
—500, —1/2. If a positive number stands first in a line, the sign is
usually omitted as understood; thus 3—1 = 2 but -1+3 = 2.
(3) Rational or irrational. For example: rational 0.6, 1/3, 22/7;
irrational 7, V2. Note that a rational number can be expressed as the
42
Arithmetic, algebra and trigonometry 43
ratio of two whole numbers, an irrational number (also called a surd)
cannot. Examples of the latter are the ratio of the circumference of a
circle to its diameter, called 7 and approximately equal to 22/7 or
3.14159; and the number which when multiplied by itself equals 2,
approximately 1.41421.
(4) Terminating, recurring or non-recurring. Some numbers cannot
be expressed exactly in decimal notation, others can. For example,
500/512 = 0.9765625 exactly, that is the decimal number termi-
nates, but 1/3 = 1.33333--, the 3 recurring for ever: this is written as
1.3. Sometimes a string of numbers recurs, e.g. 8/7 =
1.142857142857142857---, written as 1.142857. In decimal nota-
tion irrational numbers do not terminate and do not recur either —
they just go on for ever. Consequently an irrational number can never
be expressed exactly either in decimal or as a fraction. Thus 7=22/7,
the signs = or = meaning ‘approximately equal to’.
A computer can only work to a limited number of ‘significant
figures’, so all recurring and irrational numbers as well as whole
numbers with many digits have to be approximated. ‘Significant
digits’ exclude leading zeros of numbers less than one and trailing
zeros of large numbers. Thus 23 100 000 and 0.001 25 both have
three significant figures. A version of BASIC displaying results to eight
or ten significant figures can express 500/512 exactly as 9.765625E—
1 but a version displaying only to six ‘sig fig’ would round it off as
9.76562E—1. To prevent errors building up due to repeated round-
ing-off in long calculations a computer actually works to one or two
more significant figures than it displays. These are called ‘guard
figures’. The Oric displays results to nine significant figures.
(5) Even or odd (of integers, i.e. whole numbers). Even numbers
divide exactly by 2; odd numbers don’t. Zero is, by convention,
considered to be an even number.
Operations on numbers
Numbers can be added, subtracted, multiplied or divided. Note that
2+3=3+2and2x3=3x2but5—14#1-—5and5+1#
1 + 5; # means ‘does not equal’. > means ‘greater than’, thus 3 > 2;
< means ‘less than’. In BASIC we use <> or >< instead of #,
* instead of X and / instead of +.
When adding or subtracting:
even plus or minus even = even
even plus or minus odd = odd
odd plus or minuseven = odd
odd plusorminusodd =even
44 Arithmetic, algebra and trigonometry
and when multiplying:
even times even = even
even times odd = even
odd times even = even
odd times odd = odd
In the case of division, the result may be even, odd, or a fraction
(proper or improper), depending on the two particular numbers.
When denoting several arithmetic operations, ambiguity could arise.
Thus, does 2+ 3X 4+5mean5 X9=450r2+12+5=19?In
writing out a sum we conventionally avoid ambiguity by the use of
brackets:
(2+3) X (4+5)=5X9=45
We have already seen that in BASIC there is a clearly defined ‘pecking
order’ in which operators are evaluated, and, without the brackets, a
microcomputer would have come up with 19 as the answer to the
above sum.
Powers
The area of a square carpet with sides three metres long is 9 square
metres, written 9 m?, since 3 X 3 = 9. Similarly, the volume of a
square box with all edges 10 cm long is 10 x 10 X 10 = 1000 cm’,
i.e. 1000 cubic centimetres. (Cubic centimetres was formerly
abbreviated to cc, 1000 cc being one litre.)
This is alternatively expressed as ‘3 to the power 2’ and written as
3? where 2 is called the index; i.e. 3” = 9. Similarly, ‘10 to the power
3’ is written as 10°; i.e. 10° = 1000. Thus ‘4 to the power 4’ = 4* = 4
x 4 x 4 X 4 = 256, even though we can’t imagine a four-dimen-
sional figure.
Powers of ten are particularly important. Note that as 10 x 10 x 10
x 10 X 10 X 10 = 10° = 1 000 000, we can write the number
1 324 625.7 as 1.324 625 7 x 10°. (We are using the preferred
modern convention of gaps to divide up large numbers rather than
commas.) Writing the index higher than the number (as in 10°) is
inconvenient on a VDU screen so an alternative convention is
adopted: for example 1 234 000 can be written 1.2346.
Malpas and id dividing powers of anumber. Since 2? x 23 = (2 x 2)
x (2 X 2 X 2) = 25 = 2%*3) to multiply any two powers of (the same)
number we simply add the indices. Also 32/32 = (3 X 3X 3) +(3 X 3)
= 33°? = 3! or just 3: i.e. to divide, we subtract the index of the
number at the bottom from the index of the number at the top.
Arithmetic, algebra and trigonometry 45
Negative indices. Now 2? + 2? = 2?-)) = 27! but 4 + 8 = 12, so
27' = Va. Likewise, 10-2? = 1/10? = 0.01. We can express this
symbolically (algebraically) for any number A and any power or
index nas A~" = 1/A”.
Fractional indices. Does 4°° or 4"? mean anything? Let’s assume for
the moment that it does; then according to the rules above, 4°° x 4°
= 410.5 +05) — 4! or just 4.
So 4°° is that number which, when multiplied by itself, equals 4. So
4°° = 2 and 125"? = 5, etc. A°* or A'” signifies the square root of A,
and can alternatively be written VA. (The BASIC instruction SQR(A)
will also return the square root of A.) Roots of numbers will often be
irrational, for example 10°° = 3.162---.
Thus indices may be positive or negative, whole or fractional.
Again on the display or VDU we avoid writing indices in the air. 23 is
written 2 f 3, 4°° as 47.5, and 14.37' as 14.3 ? —1.23.
There are lots of other operations we can perform upon numbers,
but it is convenient to use letters to denote the numbers and to
express the operations as formulae, so let’s now look at the basic
principles of algebra.
Algebra
In algebra we are concerned with the relationships between
numbers; relationships which are constant whatever the particular
values of the numbers. A simple example of this is the relationship or
formula F = 9C/5 + 32. (9C means 9 times C, written 9*C ona VDU.)
F and C are called ‘variables’, because they can take any value. Since
the formula defines F in terms of C, the latter is called the independent
variable and F the dependent variable. Here, F can be the tempera-
ture in degrees Fahrenheit and C in degrees Centigrade.
A formula such as this is neither true nor false, it is simply a defini-
tion — a definition of how to calculate a number called F given a
number called C. It is true that if we let C mean the temperature in
degrees Centigrade, then values of C more negative than —273°
Centigrade (absolute zero) do not exist. But this does not make the
formula invalid; it is the range of the particular variable ‘degrees
Centigrade’ that is limited.
Equations can be manipulated and remain valid provided we
always do the same to both sides. Thus, subtracting 32 from both
sides of the above equation gives:
F-—32=9C/5
46 Arithmetic, algebra and trigonometry
and multiplying both sides by 5/9 gives:
5/9 (F — 32) =C
Now, C is the dependent variable, expressed in terms of the indepen-
dent variable F.
One great advantage of algebraic notation using a letter to
represent a number is that it enables us to solve directly problems that
otherwise could only be solved by trial and error. For example, how
long after 12 o’clock is it before the hour and minute hands of a clock
are again coincident? Let the answer be ‘t’ hours, where one hour
corresponds to one-twelfth of a revolution on the clock face. Then,
since the minute hand revolves twelve times as fast as the hour hand,
we have
12t-—12=t
where t is not only the answer in hours, but also the number of
twelfths of a revolution made by the hour hand. Adding 12 to, and
subtracting t from, both sides gives
11t = 12
whence t = 1!/11 hours or 1 hour, 5°/11 minutes.
Progressions or series
A list of unrelated numbers such as 1,3.5, —4.22, 22.7 is a sequence
but, where we can see a unique pattern which enables us to predict
further numbers in the list, e.g. 1, 4, 7, 10, 13 (each number three
larger than the last), we have a ‘series’, which is said to be made up of
‘terms’. In fact, the example is an arithmetic progression, where the
n" term is equal to 1 + 3(n — 1). In general, if a is the first term and d
the difference between any two consecutive terms, then the n" term t,
=a+(n—1)dand the sum of the first n terms Sn = n(a + (n — 1)d/2).
Arithmetic progressions are widely used in programming — the
FOR-NEXT instruction is an example.
FORI=JTOKSTEPL
defines an arithmetic progression where a = J andd = L.
If each term of a series is r times as large as the preceding one, we
have a geometrical progression. The general form is a, ar, ar’, ar’, ----
and clearly the nth term is ar”—" or a*r t (n—1) in VDU terminology.
An example is a bacterium growing in a culture medium. Suppose
cells divide every hour and we start with a single cell. After one hour
Arithmetic, algebra and trigonometry 47
there are two cells and, an hour later, these divide: 1, 2, 4, 8, 16, etc.
Thus the geometrical progressions describe, among other things,
the growth of a population. The population does not increase the
way it does because a mathematical ‘law’ forces it to; it’s just that
some mathematical relations describe natural processes very
accurately. Other processes may be only approximately described
by a mathematical relationship, and some mathematical relation-
ships do not describe any known physical process. Sometimes, a
mathematical function is evolved which has no application at the
time but only later, as with ‘Krénecker’s Delta’. This was invented as a
pure flight of abstract mathematics but later came in very handy in the
theory of radio-wave propagation.
The geometrical progression also describes compound interest,
i.e. where the interest is not withdrawn but reinvested to add to the
principal — the sum originally invested. Suppose you invest £1 at 100
per cent per annum compound interest (you should be so lucky!)
then after 1 year you would have £2 invested, after 2 years £4, etc.
The exponential function
Suppose instead of receiving 100 per cent interest on your £1 paid
annually, you received 50 per cent compound paid every 6 months,
then after 6 months you would have £1.50 and at the end of the year
you would have not £2 but £2.25. If it were 100/12 per cent
compound paid monthly you would have £2.61 after one year while
if it were 100/365 per cent paid daily you would have, to be precise,
£2.7145627--- after one year. If the interest were 100/n per cent paid
Figure 6.1 The exponential function
48 Arithmetic, algebra and trigonometry
at intervals of 1/nth of a year where rn was very very large (tending to
infinity), at the end of the year you would have £2.7182818---.
This irrational number 2.7182818--- is a very special number
called ‘e’. At the beginning of the year, the rate of increase, defined as
100/n per cent in 1/n th of a year, is 100 per cent per annum. At the
end of the year, the rate is still 100 per cent, but now of course it is
2.7182818-- that is increasing at this rate, as shown in Fig. 6.1.
Indeed, at any time, for this ‘exponential function’, the rate of
increase is equal to its present value. At this rate of increase, after P
units of time an initial value of unity will have increased toe’ (ore
P), i.e. 2.7182818-- after one unit of time; 7.389---- after 2 units, etc.
If the rate of increase is, say, 10 per cent, then after time P the initial
value will have increased by a factor e°'”.
Logarithms
Since 100 x 1000 = 107 x 10? = 10**3 = 10° = 10 000, we can
work out multiplication sums by adding indices instead. 2 is called
the ‘log to base 10 of 100’ because 10? = 100. Now 10°° = 3.162--
and 10°75 = 5.623-- so 3.162 X 5.623 = 10'.
Logarithms to base 10 can be looked up in log tables and, in effect,
a set of log tables is built into many home computers (though usually
to a different base). Likewise, 10':75 (called the antilog to base 10 of
1.25) can be looked up in a set of antilog tables (or by using log tables
in reverse) or calculated by the computer as, for example, 10 f 1.25
= 17.783. The log to base 10 of a number N is written logi) N,
though the subscript ; is often omitted.
We could alternatively use any other number as the base of
logarithms, and logs to base e are called natural or Napierian logs.
The natural log of N is written as£n N, though unfortunately some
home computers show this on the VDU as LOG(N). The natural
antilog of N, i.e. e%, appears on the VDU as EXP(N). Oric does it
properly. LOG(X) returns the log of X to base 10, while LN(X) gives
the natural log of X.
Trigonometry
Trigonometry, or trig for short, deals with angles and their relation to
the lengths of the sides of a right-angled triangle. Figure 6.2 defines
the various trig functions. The names of the functions and their
abbreviations are:
sine sin
cosine cos
tangent tan
cosecant cosec
Arithmetic, algebra and trigonometry 49
secant sec
cotangent cot
Suppose sin A = s, then arcsin s means ‘the angle whose sine is s’,
i.e. A. Similarly arccos s and arctan s, signify the angle whose cosine
For any right angled triangle, such
as that shown:
SINA= a/c
COSA= dK
SINA
COSA
TAN A= @/p =
i
SEC A= C/p = COSA
1
COSEC A= C/a=sinan
1
COTAN A= b/, “TANa
also,
SIN B = b/c = COS A etc.
Figure 6.2 The trigonometric ratios
or tangent is s. Angles are measured in degrees, radians or occasion-
ally grads. There are 360 degrees in a circle, e.g. the minute hand ofa
clock rotates through 360 degrees in one hour.
Figure 6.3 shows a segment of a circle where the length of the
curved line or ‘arc’ a is equal to the radius. The angle A is 57.296° (°
signifies an angle measured in degrees) and this is called one radian, 1
rad. As the circumference of a circle is 2 7 times its radius, it follows
that there are 27 radians in a circle; 27 rad = 360°. If the angle A is
very small, much less than 0.1 rad, then sin A = tan A = A rad (=
means approximately equal to).
The curved length ‘a’ (an arc of the circle) divided by
the radius ‘r’ equals the angle ‘@’ in radians.
Hence a= r 9 and if a= r then 0 = 1 radian.
1 radian 4 57.296°
Figure 6.3 Arc of a circle
50 Arithmetic, algebra and trigonometry
Grads are only occasionaty met; there are 400 of these in a circle,
so 1 grad is 1 per cent of a right angle. Like most personal computers,
Oric only handles angles in radians, so angles in degrees or grads
must first be converted into radians.
There are a great many useful relationships among the trig ratios
and these will be found in any good book on the subject, but we
mention only one here as it has practical application to a home
computer. The repertoire of BASIC functions of such a machine might
typically include SIN, COS and TAN, from which cosec, sec and cot
are easily derived by taking the reciprocal. (The reciprocal of a
number is 1 divided by that number; e.g. the reciprocal of 4 is 1/4.)
However, of the inverse trig functions — arcsin, arccos, etc. —
typically only arctan is provided. To find, say angle A given sin (A) we
therefore calculate tan (A) from sin (A) and then the computer can
give us arctan (A) directly.
It is a property of any right-angled triangle (see Fig. 6.2) that a?+ b?
= c’. Dividing both sides of this equation by c”, we get
a b — ¢ a\? b\? _
5 aa 5 or (2)'+ (2) =1
Thus, sin? A + cos? A = 1 (sin? A means the same as (sin A)*). We can
rearrange the equations as cos A = V(1—sin? A). Thus if we know sin
A and want to know the angle A, we note that:
ae
sinA
= sinA
cosA Vol —sin2A)
The BASIC abbreviation for arctan is ATN, so if M = sin A we find
arcsin M (i.e. the angle A) from
tanA=
A=arctan M
—arcian 4 — M2)
or, as a BASIC instruction
A= ATN (M1 —M ¢ 2) 7.5)
We don’t have to write this out in full each time we want to find the
angle whose sine is A. Appendix G in the Oric manual explains how
we can use the DEF FN (define function) command to define a
function ASN(A) to return the arcsine of A, and similar functions.
Binary numbers and
Boolean logic
This chapter explains binary, hexadecimal and BCD notation and
briefly explains how the individual electronic circuits called gates (of
which there are thousands inside Oric) can add, subtract, compare
numbers, etc. If you are new to computing, | suggest you skip this
chapter for now. It will come in useful later on, perhaps as an intro-
duction to Chapter 13. If and when you know your way round Oric’s
facilities in BASIC thoroughly, you may want to tackle machine code
programming. At that stage, familiarity with the contents of this
chapter is not only useful but essential.
The binary number system
We normally count in tens, called the decimal system. In the decimal
system, besides 0 we have a separate symbol for each number up to
nine, and only put a 1 in the tens column when we run out of single
figures. Had the Almighty created us with only one hand apiece we
might have counted in ‘quintal’ — fives — thus:
0,1,2,3,4,10 (meaning 5 in decimal), 11 (6), etc.
The individual electrical circuits used in a computer don’t have
even five different sorts of ouput, only two —©FF or ON, i.e. low or
high voltage, usually denoted 0 and 1 respectively. Instead of ones,
tens and hundreds columns, etc. as in decimal (or ones, fives and
twenty-fives as it would be in quintal), in binary we have ones, twos,
fours columns etc., and only the digits 0 and 1. While the decimal
number 937 means nine hundred plus three tens plus seven, a binary
number such as 110101 means one times 32 plus one times sixteen
(no eights) plus one four (no twos) plus one, or 53 in decimal. And we
say that 110101 is a six binary digit number, or 6 bifs for short.
Addition and subtraction of binary numbers obey the usual rules of
51
52 Binary numbers and Boolean logic
arithmetic, observing ‘carries’ and ‘borrows’ as appropriate. Since 0
and 1 are the only digits used, a two represents a carry to the next
column thus:
11101 and 11101
+1011 —1011
101000 10010
Microcomputers commonly use eight-bit numbers. A 1 in the left-
hand column (the ‘most significant bit’, or MSB) corresponds to 128,
the next MSB to 64, etc., so that 11111111 (the highest number that
can be represented with eight bits) is 255 in decimal. An eight-bit
binary number is called a byte.
You can see that to represent large numbers in binary notation
needs a lot of bits. ‘Hexadecimal’ notation is a method of denoting
the long streams of Os and 1s of binary in a more compact way. A
four-digit binary number can represent any number from 0 to 15
inclusive, and hexadecimal, or hex for short, is in effect counting to
base sixteen. We use the letters A to F to represent the decimal
numbers 10 to 15 respectively. Thus two hex digits can represent one
byte. (A four-bit binary number is sometimes called a ‘nibble’.) 175 in
hex would be AF (as F is 15 and the A represents ten 16s) and 119 in
hex would be 77, pronounced ‘seven seven hex’ to avoid confusion
with seventy-seven.
256 128 64
to)
w
nN
a
127
128
255
256
CHOH# COOK COCO OP RHP HR HH HOD DOO O CO @
CH OoH HOOK HF OCOCOP HHH OOO OFF KH OOCO A
CKOK OH OK OK OOK HK OOHKHHOOKHOOHKHOO By
OM OHM OK OK OK KOH OH OK OK OK OK OK OKO He
eooooooocooococcoCoCeoCoCeoCeoOeoOeoOeC oC COCO CSe
eooooooooococooCoCoCoCoOeoCeoOCOeCCOC CC CCOCSD
eooooocooeooo ooo oOeo oOo CC OOOO CO CCO CSD
mere oooooocoooooeoeoeeoeoeoeCeoCeCCCCCCSD
eoorKKH coe C CCFC OOO COC CCC OCC CCCSG
ecooorooocoocoeocoeoeeoeCeoCeCCCcCCCSD
mere ooooooooooooCoCCoCCoCeCCoOeoOC OCC CC CSO
oorroorKrK co oooeoeoeoeoeoeC oC oOeCC COC CSO
RK OCOCOF KF KF OF Ke ee ee ee HOODOO COC OCC SO
oorooroooeKrooocooooOoOK¥KcoocooCooOcCSe
meroroooocoorrrK KO OCOCCOOKFK KK OOOO
moor cor ooorKOOoOKrrKooooK~KooKrKoo
CK CHK OH OH OHH OH OH OH OH OH OH OoHOoHe
to)
t+)
0
0
(1)
i)
t+)
to)
(0)
te)
()
to)
0
0
i)
(1)
0
te)
te)
0
0
1)
0
)
0
1)
1
(oR M-B-M-M- MoM -M-M---N---B--n)
OrorKK CODD DDFD OCC ORCC OC COCO CCCOOCD
(de-N M- N-NMR -M-N-N-----e-e)
CrOoKFOCOOKFKHeHe KH CODD DOO OC OCC COC OCOOOSO
ONMBYNAANK KKH KH DOD CCODOOCOCOCOCOCS
SONONMFWONFWKONMONDYPLYOBiM HV e&wWHKO
(2) (b) ()
Figure 7.1 (a) binary; (b) hex (hexadecimal); (c) BCD (binary coded decimal)
Binary numbers and Boolean logic 53
In programming Oric, a plain number or one with the suffix d is a
decimal number, e.g. 25 or 25d; a hex number would be indicated
by anh suffix or a # prefix thus, 25h or #25 (i.e. 37d).
Yet another system based on binary is BCD notation. Binary Coded
Decimal is simply decimal notation but with the decimal digit in each
column replaced by the corresponding four-bit binary number; thus
79d in BCD would be 0111 1001. Figure 7.1 compares decimal,
binary, hex and BCD notation.
The largest number that can be represented by two bytes (or four
hex digits) is FFFF or, reading from the LS digit on the right, 15 + (15 x
16) + (15 X 256) + (15 X 4096). This comes to 65 535 and is in fact
the maximum number of memory locations an eight-bit micro-
processor-based computer can address using ‘double length’ or ‘two
byte’ addressing.
Now 2'° = 1024, so a ten-bit binary number can represent any
decimal number up to 1023 (i.e. 1024 different decimal numbers if
you include nought). This is roughly one thousand and is usually
called 1K, where the capital K indicates 1024 rather than 1000
exactly — which would be a small k as in kilometre, km. Thus our
microcomputer is said to have a 64K addressing range. What about
representing negative numbers in binary notation? Negative numbers
can be represented in what is called ‘two’s complement’ notation.
Here, we sacrifice half the range of positive numbers that a binary
number can represent to enable us to express negative numbers, as in
the simple three-bit example in Fig. 7.2.
Two’s complement notation has the following advantages:
(1) All the positive numbers including 0 have their normal binary
significance except that there must always be a nought in the MSB
(left-hand place). Thus in the three-bit example in Fig. 7.2 the largest
possible positive number is 011, i.e. 3d.
Straight Twos
Decimal binary Decimal ,complement Example: for 3—2
7 111 3 ' 011 +3 simply add 3 and(—2)
6 110 2 ' 010 ae
5 101 1 ' 001
4 100 0 : 000 011 --3
3 011 -1 ‘1a. ,1 10 ---+(-2)
2 oe 2 i: 110 *+-2 si007
1 001 3 $101 ’
0) 000 —4 ' 100
Ignore the ‘carry’
4
Unused notional
fourth column
Figure 7.2 Simple illustration of two’s complement notation using three-bit
numbers. In microcomputers we use eight-bit numbers, representing any
number in the range — 128 through zero to +127. The MSB can be considered
as the sign bit: 0 for a positive number and 1 for a negative number
54 Binary numbers and Boolean logic
(2) Any two numbers — both positive, both negative or one of each
—can be simply added and the result will be correct, bearing in mind
that any carry from the MSB is ignored.
(3) Given a positive number A, then — A is simply derived, and the
same rule turns a negative number into the corresponding positive
one.
Two’s complement is the only notation for expressing negative
numbers as a string of binary digits (without resort to a minus sign) that
possesses all of these important and useful properties.
Subtraction of binary numbers can be carried out manually by the
normal rules of arithmetic, borrowing from the column to the left of
the MSB if needed, but a computer would instead add the two’s
complement of the number to be subtracted: In the example in Fig.
7.2 we added —2 to 3 instead of subtracting 2. The general rule for
obtaining the two’s complement of a number is to change all the Os to
1s and vice versa and then add 1. Thus:
010 — 101 + 001 = 110
(+2) (—2)
110 — 001 + 001 = 010
(—2) (+2)
For simplicity we have used three-bit numbers in the examples but
the same scheme works for any number of bits and thus applies to
bytes — ignoring of course any carries to the ninth column. Thus in
two’s complement form one byte can represent any number in the
range —128 to +127.
Boolean algebra
Boolean algebra is a system of rules for describing the truth or false-
hood of a statement as a function of certain other statements. It is
named after its inventor George Boole, 1815—1864, English
mathematician and logician, a native of Lincoln and from 1849
occupant of the Chair of Mathematics at Queen’s College, Cork.
Boolean algebra applies to particular statements — or rather, in the
logicians’ term, ‘singular’ statements, such as ‘The dining room door
is shut.’ The rules for the correct manipulation of ‘universal’ and
‘particular’ statements (such as ‘All birds are oviparous’; ‘Some dogs
are rabid’) were systematised over two thousand years ago in the
Organon of Aristotle, where he dealt with the syllogism and other
logical constructions. However the Boolean system was probably the
first providing a useful systematic treatment of singular statements,
Binary numbers and Boolean logic 55
i.e. statements dealing with individual, unique situations.
Some simple illustrations are given in Figs 7.3 and 7.4 which show
situations corresponding to the AND and OR functions of two inputs
in terms of ‘truth tables’. Included in these figures are the diagram-
matic symbols and truth tables for AND and OR gates as widely used
in computers. They are included in this chapter for completeness.
A B x
Is it raining Have forgotten Will get
umbrella wet Logical examples of
No No an AND gate
No
No
Yes
Switch A Switch B
+ =
Battery
Battery circuit AND gate
Voltage levels at inputs
and output: 0 = OV approx,
A 1 = +2.5 to +5V approx.
x
=.
B
0 Symbol for AND gate
1
0
1
Figure 7.3 The AND function Alternative symbol
x
Have umbrella Have plastic mac Will keep dry
No N No Logical example of
No Yes an OR gate
Yes Yes
Yes Yes
wo
Switch A
Switch B
x
Symbol for an OR gate
A
x
B
Figure 7.4 The OR function Alternative symbol
B
0
1
10)
1
56 Binary numbers and Boolean logic
Figure 7.3 corresponds to the possible combinations of the state-
ments: ‘It is raining’; ‘I have forgotten my umbrella’; ‘I shall get wet’.
Calling the two antecedent statements A and B and the conclusion X,
we have the AND function because X is only true if A and B are both
true. Similarly with the torch bulb and two switches in series — again
we have the AND function. The works of a computer make extensive
use of ‘gates’, and Fig. 7.3 also shows an AND gate where we define
YES, TRUE or ON as a one; and NO, FALSE, or OFF as a zero. The
truth table is of exactly the same form as the other two examples.
Figure 7.4 shows the OR function — here the statements might be
(assuming that it is already raining): ‘1 have an umbrella’; ‘I have a
plastic mack’; ‘I shall keep dry’. We get a different truth table from
Fig. 7.4 and again we showa torch bulb analogy and a gate circuit, all
with the same truth table. Note that the OR function does not exclude
both possibilities being true — whereas sometimes in normal speech
we rule out or at least discount this possibility. Thus if the key won't
open the lock we usually conclude that either it is the wrong key or
possibly the lock is jammed, though of course it could be that we are
doubly unlucky and both reasons apply. In Boolean notation A OR B
is written as A+ B; AAND BasA.B.
=p
Symbol for EXCLUSIVE OR gate
—{ e)—«
| ®)
B
Alternative symbol
A ge
Line Hall
switch
Mains
Neutral Landing light
Figure 7.5 The EXCLUSIVE OR (EXOR) function
Figure 7.5 illustrates the EXCLUSIVE OR function — sometimes
abbreviated EXOR — in terms of the ‘two-way switch’ used to control
the light on the landing in most homes. Other analogous examples
are the signs of two numbers and the sign of their product, and the
oddness or evenness of two numbers and their sum. In Boolean
terms, X =A®@B.
The AND and OR functions have been illustrated as having only
two inputs, but larger numbers of inputs are perfectly possible. For
example: have cash (A); have chequebook (B); have credit card (C);
Binary numbers and Boolean logic 57
can buy goods (X); is equivalent to a three-input OR gate. In Boolean
notation this isX =A +B+C.
Another important Boolean term is ‘negation’: this is simply the
contradiction of a proposition. Thus if a switch is ON it is not OFF,
which is to say it is not (not ON). The negation of a statement or
condition is indicated by placing a bar over the top thus:
A A
The switch is on The switch is not on
Hence, as we have seen, A=A.
A number of useful, interesting and important results follow.
1 (A+B) =A.B Quite simple really; if it is untrue that either A or B is
switched on, then both A and B must be switched off. Try checking
the following results for yourself
2 AB=A+B
3 A.A = 0 where 0 (zero) signifies ‘untrue’
4A+A=AA=A ~
5 A®B=A.B +A.B = (A.B) . (A.B)
Noting that A + B = X corresponds to an OR gate, A.B = X to an
AND gate and ‘bar over’ to negation as provided by an inverter (see
Fig. 7.6), we can see that an OR gate followed by an inverter is equi-
valent to a NOR gate, and likewise for AND and NAND gates.
A —>— x
X=A
The inverter x= X= (A+B) = AB
Showing how a NOR gate is equivalent to
an OR gate followed by an inverter
= Sess
Truth table for a two input NOR gate Symbols for a NOR gate
aD—
Eight input NAND gate EXCLUSIVE NOR gate
IoOnNMoOWyY
Figure 7.6 Example of the function of INVERSION
58 Binary numbers and Boolean logic
These equivalents enable the designer of logic circuits to use
different combinations of gates as most convenient to obtain a
particular logic function or truth table. Thus in Fig. 7.7 both arrange-
ments produce the EXOR function, though this is also available to the
user of integrated circuits as a gate in its own right.
Gates can be connected together to perform various arithmetical
functions, the simpler arrangements working in binary. More
complex arrays are used for operations in decimal, but the principles
X = (A+B).(A-B)
AB - AB
(A+B).(AB) = (A+B).(A+B)
= A(A+B)+B(A+B)
= AA+AB+BA+B.B
HenceX= ABt+AB
Figure 7.7 Showing how different arrangements of gates may be used to
provide the same logic function — in this case the EXOR function of two inputs.
(a) This arrangement uses only three gates; (b) This arrangement uses only one
type of gate — the two-input NAND. Note that by connecting together all the
inputs of a NAND or a NOR gate it can be used as an inverter
are the same. Figure 7.8 (a) shows a gating circuit which will add
together two single-bit binary numbers, and the rules of Boolean
algebra can be applied to check that the circuit does indeed perform
in accordance with the truth table given. Usually, of course, we will
want to add binary numbers of several bits each, say two one-byte
numbers, so, as well as a carry output to the next stage, there will be a
Binary numbers and Boolean logic 59
Truth table
From
previous
stage Co aul Sj (sum)
u
Tobe f Al
Sided (e) adder Cy
To next stage
Halt
Cc
Figure 7.8 Basic adder circuits
carry input from the previous one. Thus we need a ‘half adder’ as in
Fig. 7.8 (a) for the two least significant bits, but for each of the other
bits we need a ‘full adder’ as in Fig. 7.8 (b) — again the appropriate
truth table is shown.
The addition of two one-byte numbers would be one of the func-
tions of the ALU (arithmetic and logic unit) in a microprocessor, and
the carry output from the eighth stage is the ‘carry bit’ from such an
addition. This is kept in a special store in the microprocessor and is
capable of being tested by a later microprocessor instruction. The
ALU can also AND or OR whole bytes. Here, the appropriate func-
tion is performed between corresponding bits in each byte. Thus
if A = 10101010
and B = 01010101
then A+B =11111111 (OR function)
and A.B = 00000000 (AND function)
This is useful for ‘masking’, a concept which is explained in Chapter 13.
Strings and things
The manual explains how Oric deals with words — string handling —
in detail and the relevant chapter is worth studying closely. As it says,
PRINT A will result in zero being printed, provided of course that the
variable A has not been set to some other value. Any letter or group of
characters starting with a letter may be used to name a numeric vari-
able and, unless instructed otherwise, BASIC will assume that the
initial value of the variable is zero. Similarly, any group of characters
starting with a letter and ending with $ may be used to name a string
variable. Unless instructed otherwise, BASIC will assume the initial
value of a string variable is null, i.e. like inverted commas with
nothing in between. Thus, if you run
10 A$ = “HELLO”
20 CLS
30 PRINT A$
Oric will print HELLO and then leave a blank line before its READY
message. If, however, you delete line 10 and then run the program,
there will be a blank line where a null A$ is printed, followed as
before by a blank line and then READY.
MID$(A$,2) is a particularly useful command. When applied
successively to the string A$, it will shorten the string down to nothing
by chopping off the first letter at each stage. Thus, if
A$ = “HELLO”
then
A$ = MID$(A$,2): PRINT A$
60
Strings and things 61
will print ““ELLO’’. This may not seem very useful in itself, but one
would in practice have done something useful in the meantime with
the H that has been chopped off. Try running
10 A$ = “HELLO”
20 B$ = A$
30 CLS
40 INK 0: PAPER 2
50 FORL = 1 TO LEN(A$)
60 N = ASC(A$): A$ = MID$(A$,2)
70 PLOT L, 10, N + 128
80 NEXT
90 PRINT A$; B$
This program shows how you can print selected messages in inverse
colours at any required point on the screen. Don’t worry about how
the inverse colours — in this case white on magenta in place of black
on green — are produced; that is explained in Chapter 9. The
program illustrates how the ASC and MID$ commands are used in
the FOR—NEXT loop to dismember A$ in order to process it into
inverse colours. A$ is then plotted part-way down the screen. Line 90
prints HELLO, at the top of the screen naturally, since that is where
printing starts after CLS. It only prints one HELLO: B$ was set equal to
HELLO in line 20, but the loop in lines 50-80 has dismembered A$
completely — there’s nothing of it left! If you now LIST, it will over-
print your colourful HELLO, so care is needed with the screen format.
For example, if you add a line 85 thus
85 FOR X = 1TO 15: PRINT: NEXT
the black HELLO will appear under the inverse HELLO and now,
when you list, all is well. Note that once plotted, the inverse HELLO
will scroll up with the rest of the screen display.
Here is a program to illustrate how both numeric data and string
data can be held in the same DATA statement
10 REM FRENCH NUMBERS
20 CLS
30 FOR X = 0TO3
40 READ N, N$
50 PRINT
60 PRINT N; “ IS SPELT’; N$
70 NEXT
80 DATA 0, ZERO, 1, UN, 2, DEUX, 3, TROIS
Provided that the READ statement finds a number and a string in the
right order each time it reads and there is enough data for four reads (0
62 Strings and things
to 3 inclusive), all will be well. If we had 0 TO 4 for X in line 30 we
would get an OUT OF DATA ERROR IN 40 message, whilst if in line
80 we had 3 and TROIS interchanged, we would get a SYNTAX
ERROR IN 80 message.
Sorting
The manual gives an example of a sorting program. This is a very
important class of program in data handling systems, where file
records have to be sorted into order. The simplest type of sorting
program is the ‘bubble sort’, where wrongly placed early entries, on
repeated passes of the program gradually bubble up to the head of
the list. The trouble with this sorting program is that, as the file (or list
of items) to be sorted gets longer, the time taken to sort them goes up
by leaps and bounds. Other sorting programs such as the ‘shell sort’
are more efficient and, at the expense of occupying more memory
space, a hashed system of file records can be sorted very quickly.
The topic of sorting is covered regularly in articles in the various
magazines devoted to personal computing, such as Practical
Computing, Personal Computer World, etc. and will undoubtedly be
covered in forthcoming issues of your very own magazine Oric
Owner. Indeed, there is an article on this topic in the very first issue of
the magazine.
The TAB command
Finally, a word about the notorious TAB bug. The SPACE command
inserts a number of spaces in a PRINT list; for example
10 PRINT ‘‘L’’; SPC(5); ““M’”’
will print, when run,
L M
The TAB command should work like the tab key on a typewriter, so
that
10 PRINT “L”; TAB(10); “M”
should print
L M
Strings and things 63
while
10 PRINT ‘LITTLE’; TAB(10); ““M’”’
should print
LITTLE M
In other words, where SPC counts spaces from the end of the last item
printed, TAB counts from the beginning of the last item — just what
you need for printout of data in columns. In fact, a computer’s TAB
command is more intelligent than a typewriter’s TAB key. If in our
example we had had not LITTLE but a word with 10 or more letters,
the TAB(10) command would leave one space after the word for
clarity and then print M.
Unfortunately, on early models of Oric, including mine, the TAB
command does not work like this — in fact it does not work at all,
being completely ignored. But from Issue 2 of the invaluable Oric
Owner magazine, | learn that TAB works like SPC if you add 13 to the
parameter, e.g. TAB(23) = SPC(10). This is interesting but not terribly
useful, so | have worked out a scheme which really does provide the
TABulation function (well, almost).
S B¢="NEXT"
10 DIMA$(4)
20 PRINT"VALUE: — ist
30 FORI=1T04
40 READAS (1)
SO PRINTSPC(10) s;AS(T);
60 PRINTSFPC (12-LEN(AS(I))) 3 "NEXT":
79 PRINTSPC (9-LEN (BS) ) 3 "LAST"
80 NEXT
90 DATAONE, THREE,NINETY NINE, TEN
VALUE: - ist 2nd 3rd
ONE NEXT LAST
THREE NEXT LAST
NINETY NINE NEXT LAST
TEN NEXT LAST
Figure 8.1 ‘TAB BODGE |’ plus sample printout
Figure 8.1 shows a program designed to illustrate ‘TAB BODGE |’,
together with a sample of the tabulated printout it produces. The trick
is to use LEN to find out how long the string to be printed in a given
64 Strings and things
column is, and subtract this from the column spacing to give the
appropriate parameter value for SPC. If you are printing not strings
but numbers, you can use LEN(STR$(X)) to find the length. The
sample printout looks neat enough, but had NINETY NINE been
SEVENTY EIGHT, we would have been in trouble as line 60 would
then have calculated a negative spacing! The result would be an
ILLEGAL QUANTITY ERROR message.
S BS="NEXT"
10 DIMAS (4)
20 PRINT" VALUE: - Ist
30 FORI=1T04
40 READAS (I)
SO PRINTSPC (10) ;ASC(1) |
60 PRINTSPC (ABS (9-LEN (AS (1) ))) 3 "NEXT" §
70 PRINTSPC CABS (9-LEN (BS) )) 3 "LAST"
80 NEXT
90 DATAONE, THREE,NINETY NINE, TEN
VALUE: - Ist 2nd ard
ONE NEXT LAST
THREE NEXT LAST
NINETY NINE NEXT LAST
TEN NEXT LAST
Figure 8.2 ‘TAB BODGE II’ plus sample printout
‘TAB BODGE II’, Figure 8.2, gets round this by using the ABS func-
tion to ensure that the spacing is positive (or zero). The sample print-
out shows this, but notice the displaced LAST in the third column: a
proper TAB function would have printed it in line, as the preceding
NEXT doesn’t exceed its allocated space.
The command POS should return the horizontal position of the
cursor, so using this it ought to be possible to write a routine to imple-
ment the TAB function fully. However, on my machine the POS
command does not work. It is a fair guess that the POS subroutine is
used by TAB and that therefore if POS worked, TAB would too!
Advanced graphics
This chapter is for those who wantto get to grips with the fine detail of
how the TEXT, LORES and HIRES screen modes work. This will
enable them to exploit Oric’s capabilities to the full. However, it is not
a chapter to dive into at a first reading of the book. You can go a long
way with the information in Chapter 4 of the Oric Manual plus
Chapter 4 of this book. When you are thoroughly familiar with the
basic operation of the four screen modes described therein, you will
be ready to delve further into the mysteries of Oric ...
It turns out that there is nothing mysterious; it is all quite straight-
forward, but as there is quite a lot of detail it can seem complicated at
first. So let’s take it slowly, a step at a time, and build it up as we go
along. Do take the trouble to type in the illustrative programs given in
the text and run them to see for yourself just what happens. It is also a
good idea to save them on cassette, so you can come back to them
again later without further typing.
Before considering the four screen display modes, you must under-
stand that we are talking about three different processes. The first is
the storing in memory of data to be displayed on the screen; this is
principally what this chapter is about. The second is updating. There
are certain rules that Oric follows when updating screen information
and especially when overwriting existing parts of the display. Mostly
we can leave Oric to look after this, but in some cases it is important to
know what is going on and I’Il point it out where necessary. Thirdly,
there is the process of sending the stored data to the TV set or monitor
VDU, to produce the picture. This is a ‘real-time’ process; that is to
say, the data has to be sent repetitively at the right time in relation to
the TV set’s line and frame synchronisation signals, in order to
produce a steady, stable picture on the screen. This chore is looked
after by a special ‘gate array’ IC that is quite distinct from the ‘micro-
processor’ which is Oric’s ‘brain’, and we don’t need to know how it
works.
65
66 Advanced graphics
User-defined graphics and the LORES/TEXT screen
If you owned one of an earlier generation of personal computers and
understood how the character and graphics sets work, as far as the
Oric 1 goes you are going to have to unlearn it! If, on the other hand,
the Oric is your first personal computer, you are at no disadvantage.
The Oric’s standard character set is shown in Appendix D of the
manual. As you can see, it covers upper- and lower-case letters,
numerals, punctuation, etc. and is generally very similar to the
standard ASCII set, apart from a few special signs such as © — the
copyright symbol. Codes 126 and 127 are not listed; on my machine,
PRINT CHR$(1 26) gives a checker-board symbol, while 127 gives a
space (blank). Codes 0 to 31 are non-printing characters; they are
used instead as control codes. The Oric manual calls these ‘attributes’
and lists their use (in Connection with graphics) separately as
Appendix C. They have a different significance as ASCII codes; see
Appendix 3 to this book.
In the TEXT and LORES modes, the data stored by Oric in the
screen memory area of RAM is not sent directly to the circuit which
assembles the TV signal. Instead, the number stored is used to define
which pattern is sent. For example, if the number 65 (which corres-
ponds to a capital A) is stored at location 48060 (centre of top line on
the 48K model) then, on eight successive line scans of the TV picture,
the eight sequences of six dots stored as 1s or Os at memory locations
46600 to 46607 will be sent. Each sequence of six dots will be sent at
the right time to appear in the centre of the TV picture, near the top
(see Chapter 9 of the Oric manual for details).
The standard character set is used in TEXT and LORESO modes and
the alternative ‘teletext’ style graphics characters are used in LORES1.
Both character sets are stored in ROM and automatically loaded into
RAM by the Oric’s initialisation sequence at switch-on. Thus,
although the range of graphics characters provided is not as varied as
on many earlier personal computers, the range that can be used is
much wider; any or all of the standard or alternate (graphics)
characters can be redefined at will. The manual explains how, with
examples.
Just how many different possible characters are there? Each
character is built up of a grid of six dots horizontally by eight verti-
cally. Taking just the six dots in the top row, the right-hand one can be
on or off (corresponding to a 1 or a 0) so there are just the two
possibilities for that dot. The next one to the left can also be on or off,
so for those two dots together we have 2 X 2 = 4 possibilities. For the
whole row of six dots we have 2° = 64 possible arrangements, from
all off (00000, e.g. the top row of a lower-case letter such as ‘a’) to all
on. (This only occurs in some of the alternative characters, since in
Advanced graphics 67
standard characters the right-hand dot in each row is always a0 —to
provide the space between letters. Thus, the bar of a T is 111110.)
With 64 possibilities for each row and eight rows we have the
grand total of (2°)® = 64°, which is over 281 British billions; to be
more precise, 281 474 978 million different patterns. The number
which can be available within the machine at any one time is more
limited — namely codes 32 to 127 plus an equal number of graphics:
192 in all. You might care to try running this little mystery program,
designed to illustrate Oric’s redefinable character set.
10 REM WAIT TO SEE WHAT HAPPENS
20 REM RUN AGAIN TO RESTORE
30 FORS = # B420 TO #B799 STEP 8
40 :FORR=0TO2
50 : X = PEEK (S + R)
60 : Y= PEEK (S + 6— R) :POKES +R, Y
70 : POKES +6—R,X
80 : NEXT
90 NEXT
100 CLS: LIST
Each of the characters can appear in any one of the locations (with
certain restrictions, as we shall see) on the TEXT or LORES screen.
There are 1080 such locations arranged in a grid 40 spaces wide by
27 high — see Appendix 5. The columns are numbered 0-38 from left
to right, with an unnumbered reserved column at the left, and the
rows are numbered 0 to 26 from top to bottom. Each space corres-
ponds to a specific location in memory; these RAM addresses are
listed in Appendix 5 for convenience when you want to POKE to
them directly, rather than via PRINT or PLOT commands. Note: the
memory addresses given here and throughout this book are for the
48K version. On the 16K Oric, RAM ends at location #3FFF or (16 X
1024) — 1 = 16383 in decimal. Thus, to obtain the corresponding
addresses in the 16K machine, subtract #8000 or 32 X 1024 =
32768 from the addresses given here.)
The screen allocation in memory for the TEXT and LORES modes
actually runs from #BB80 to #BFEO, that is to say from 48000 to
49120 in decimal. This is actually 1120 spaces, not 1080 as stated
above, but the extra 40 are accounted for by the top line of the
display where the CAPS reminder, and also notices such as ‘sear-
ching’ or ‘saving’ during cassette use, appear. These 40 locations
cannot be accessed by PLOT X, Y but, like the reserved column on
the left of the screen, they can be accessed by a POKE statement. For
example, POKE 48000, 17 will provide a pleasing red background for
the whole of the top row.
The first location that can be accessed via PLOT corresponds to
68 Advanced graphics
memory address 48041, so that PLOT 0,0,’“A’’ and POKE 48041,65
will print the same character in the same place: try
10 CLS: LORES 0
20 FOR! = 1TO 10
30 POKE 48040,2: POKE 48041,65
35 PRINT
40 WAIT 50
50 POKE 48040,5: PLOT 0,0,“A”’
60 WAIT 50
70 NEXT
80 CLS:LIST
The POKEs to 48040 set the foreground colour for the row to green
and magenta alternately; since the POKE to 48041 and the PLOT 0,0
do the same, the changing colour of the A is the only indication you
will have that the program is alternately POKEing PLOTing the A. The
PRINT in line 35 (obviously an afterthought!) is to move the cursor out
of the way.
It is worth noting that here we are using 48040 to store the fore-
ground colour, even though it is in the extreme left-hand column
normally reserved for storing background colour. You can store the
attribute setting foreground colour in any position along the line and
similarly for the background colour. The foreground colour will apply
to any foreground character appearing on the rest of the line, or at
least until the foreground colour is changed by storing another fore-
ground attribute somewhere further along the line. A background
colour will apply to all consecutive spaces to its right in which some-
thing is stored, be it a printable character (standard or alternate) or a
foreground or background attribute. If nothing is printed in a square,
the background for later squares on that line reverts to black.
There is still a little more to say about the LORES screen, but it is
best left until after we have looked more closely at the topic of serial
attributes and the famous ‘bit 7’.
The HIRES screen and how Oric handles the display
The HIRES screen has a resolution of 240 locations horizontally by
200 vertically, plus three standard text lines at the bottom of the
screen. Ignoring the text lines for the moment, this gives us 240 x 200
= 48000 locations or ‘picture cells’; these are called pixels for short.
Appendix | of the Oric Manual explains the format. You will note that
the pixels run from 0 to 239 inclusive horizontally and 0 to 199
inclusive vertically. In Appendix 6 of this book | have indicated the
Advanced graphics 69
memory locations for the HIRES screen in the 48K machine for
convenience if you want to POKE to them directly.
If the machine devoted one byte to storing each pixel, this would
be a very flexible and powerful arrangement, but it would
immediately use up the greater part of memory; indeed it would
require more than the entire available random access memory in the
16K model. In fact, this exorbitant memory requirement is cut to one-
sixth, or just 8000 bytes, by storing six consecutive pixels in one byte;
this is clearly indicated in Appendix 6. Thus, in the horizontal direc-
tion, the memory format of the HIRES screen is identical to that of the
LORES/TEXT screen, requiring just 40 bytes per row. However, in the
vertical direction, the HIRES screen has 200 lines, giving our total
memory requirement for the HIRES screen of 200 x 40 = 8000 bytes,
plus of course the three lines of text.
As inthe LORES modes, selecting HIRES automatically sets the dis-
play to white on black, although we can subsequently change both
foreground and background colours at will. We saw that in TEXT and
LORES modes, the number stored at the memory
address corresponding to a particular character position on the
screen was used to call up a predefined set of dot patterns represent-
ing, say, the letter A. There is no such ‘translation’ in HIRES; six of the
eight bits in a byte determine directly six pixels.
To illustrate how the six least significant bits of a byte control six
consecutive pixels, let’s consider the top row (row 0) and the six
leftmost pixels therein, i.e. the points 0,0 to 0,5. These correspond to
memory location 40960. Run the following program:
5 | REMHIRES DEMO 1
10 HIRES
20 CURSET0,0,1
30 DRAW5,0,1
1000 WAIT 300
1010 TEXT: LIST
Line 20 will set pixel 0,0 to 1, i.e. foreground colour; in this case
white, as HIRES automatically calls up white on black and we have
done nothing to change that. Line 30 will do likewise in a straight line
to a point 5 pixels distant from 0,0 to the right and O pixels distant
from 0,0 in the vertical direction. Thus the six pixels 0,0 to 0,5 inclu-
sive will appear as a horizontal line, white on black. These six points
are defined by Oric as foreground colour (white) rather than
background colour (black) by setting the six least significant digits of
the byte stored at 40960 to 1s rather than Os. Now 111111 in binary is
32+ 16+8+4+2+1 = 63. So if we add a line to the above
program thus:
70 Advanced graphics
40 PRINT PEEK (40960)
we might expect to find the number 63 displayed on one of the three
text rows at the bottom of the screen. Try it. In fact we find not 63
but 127.
The reason for this is that in addition to setting bits 1 to 5 inclusive to
1, to indicate that all six bits are to be displayed in the foreground
colour (white) Oric makes use of a 1 in bit 6 (denoting the 64s
column) to indicate that the byte represents ‘pattern’ information to
be displayed as pixels on the screen, rather than ‘colour’ information.
Colour information is represented by a number in the range 0 to 7
(foreground) or 16 to 23 (background) and can be stored at any
location in the address range of the HIRES screen. Thus, if we POKE
18 into location 40960, it will set the background colour to green for
the whole of the top line; try it by adding 15 POKE 40960, 18 to our
little ‘HIRES DEMO 1’ program.
Two points to note here. First, unlike LORES mode, the green
background colour will apply to the end of the line, regardless of
whether any foreground is printed in following pixels or not.
Second, since bit 6 is set to zero, lines 20 and 30 cannot print the
pattern they define. As it is being used to store a colour change,
location 40960 is effectively protected against use by pattern bits. Try
the effect of changing line 20 to
20 CURSET 6,0,1
and also of changing line 15 to
15 POKE 40960,2
Attribute 2 is green again, but foreground rather than background.
Note that to change a foreground or background colour requires a
whole byte and thus ties up one memory location. We are then
unable to plot any pattern at the corresponding group of six pixels on
the screen. Remember this limitation if you wish to change fore-
ground or background colour halfway along a line.
Here’s another interesting fact. You might think that bit O of
location 40960 corresponds to pixel 0,0, bit 1 to pixel 1,0, etc.
However, if we delete line 30 of the above program, so that we only
set pixel 0,0 to foreground, line 40 prints out the content of memory
location 40960 as 96. This is 64 (a 1 in bit 6, indicating pattern) plus
32 (a1 in bit 5). So it turns out that bit 5 represents the point 0,0, bit 4
represents 1,0 and so on, to bit 0 representing pixel 5,0. Pixel 6,0 is
represented by bit 5 of the next memory location, 40961, and so on
across the top line, as shown in Appendix 6.
Advanced graphics 71
We have seen that if a HIRES screen memory location does not
hold pattern bits, then bit 6 will be set to zero. Also that the colour
codes are 0 to 7 and 16 to 23. Codes 32 to 63 are unused in HIRES
mode. As we have seen, codes 64 to 127 represent pattern codes in
foreground colour, i.e. bit 6 (the 64s column) set to 1 plus pattern bits
0 to 5 as appropriate. If bit 7 is set to 1 (bit 7 represents 128 in binary)
then the pattern bits are displayed in the INVERSE foreground colour
— codes 128 + (64 to 127) i.e. 192 to 255. Here’s a program which
illustrates this.
5 REMHIRES DEMO 2
10 HIRES
15 FORN = 40960 TO 47000 STEP 40
16 POKEN,3:NEXT
20 REPEAT
25 F=127
30 GOSUB 122
40 WAIT 100
45 F=255:GOSUB 122
50 WAIT 100
60 X=X+1
70 UNTILX=5
80 GOTO 1000
122 FORN = 40961 TO 42961 STEP 40
125 POKEN,F
127 NEXT
128 RETURN
1000 WAIT 300: TEXT: LIST
Lines 15 and 16 POKE foreground colour 3 (yellow) into the byte
corresponding to the left hand six pixels of each row. Subroutine lines
122 to 128 then POKE to set the next six pixels in each line.to fore-
ground colour. The GOSUB call in line 30 has F set to 127, resulting
ina yellow display but the GOSUB call in line 45 has bit 7 set to 1, so F
= 128 + 127. Bit 7 set to 1 calls up inverse colour, so a blue display
results. By choosing other foreground colours in line 16 you can see
which colour is the ‘inverse’ of which. It turns out that the inverse of
colour nis 7—n, so since white is 7, inverse white is O, i.e. black. You
may have noticed, in TEXT mode, that whatever PAPER colour you
choose, the cursor is always in a different colour; now you know how
it’s done.
On the face of it, the GOSUB routine in lines 122 to 128 could just
as easily have been written with a CURSET plus a DRAW command
for each line. However, on the author’s machine the FB codes do not
work as described in the manual; instead, FB codes 0 and 2 both call
up background colour and 1 and 3 both call up foreground colour.
72 Advanced graphics
Try it out on your machine; later models may have had the software
amended to operate correctly.
Our HIRES DEMO programs have been pretty unexciting up to
now, designed purely from an educational point of view to illustrate
various points relating to Oric’s screen handling routines. Here’s
another such:
10 REM HIRES DEMO 3
80 HIRES
90 P= 40962
100 FORO =1TO 18
110 FORN =0TO 34 STEP5
130 POKE P — 1,3: POKEP + N,B + 17: B=B + 1: NEXT
150 P = 40962 + O*40: B = 0: NEXT
160 FORY=6TO11
180 FOR X = 12 TO 230
190 CURSET X + M,Y,1: NEXT
200 NEXT
210 FOR Y = 12 TO 24
220 CURSET 12,Y,0
230 DRAW 218,0,2
240 NEXT
250 CURSET 12,25,1
255 Y = INT (100 + 60*SIN (A))
260 DRAW 200,Y,1
265 CURSET 12,25,1: DRAW 200,Y,0
270 A=A+.3: IFA >2*PI THEN A = 0
275 Z=Z+1: IF Z>50 THEN 300
280 GOTO 250
300 CURSET 120,100,2
500 WAIT 300
1000 TEXT: LIST
Like the other HIRES DEMO programs, after RUNning it auto-
matically returns to TEXT mode and LISTs the program. You will find
this a very useful scheme when you are developing a HIRES graphics
display — having seen the show so far, you can get straight on with
writing the next program section or modifying the existing one. If your
program is getting long, you can save more precious seconds by
using a LIST instruction in the last line such as LIST 850—. This will list
anly from line 850 (or whatever) to the end of the program. I'll leave
you to work out the detailed operation of the program for yourself,
but here are the points it’s designed to illustrate.
(a) By POKEing background colours at various places (30 pixels
apart) along a block of 18 lines, it shows how a background colour
applies to all pixels to the right until a new background colour is
defined.
Advanced graphics 73
(b) It shows how pixels in a foreground colour can be overwritten on
to background colour, except for the six pixels corresponding to any
byte used to define a background colour.
(c) It shows how repeated CURSETs could be used to do the same
job as DRAW, but only very much more slowly.
(d) It concludes with a very simple piece of animation, a line pivoted
at one end, waving up and down. As you will see, it is a very clumsy
piece of animation. See if you can improve it by getting rid of the
flicker. The way to do this is to plot the next line before deleting the
old one.
Finally, to return to the LORES screen. If you refer to the
LORESO, DEMO 2 program in Chapter 4 and enter it with lines 70 and
80 thus
70 PLOT 16,10,32
80 PLOT 17,10,68
you will get a white D plotted on a green background, just like the
preceding C.
80 PLOT 17,10,ASC(‘‘D”’)
will do the same; 68 is the ASCII code for D. If, say, N$ has previously
been set to ‘“‘D’’, then we could have used
80 PLOT 17,10,ASC(N$)
Now we saw, in the preceding section on the HIRES screen, that bit
7 of a character sent to screen controls whether the display of that
character is normal (bit 7 set to 0) or inverse (bit 7 set to 128). Asa 1 in
bit 7 indicates 128, changing line 80 to
80 PLOT 17,10,ASC(N$) + 128
will result in an inverse display. Try
80 PLOT 17,10,ASC(“‘D’’) + 128
in the LORESO, DEMO 2 program and you will now find the D
displayed in black on a magenta ground instead of white on green.
Thus bit 7 has caused both the foreground and the background to be
displayed in inverse colours. It is not a difficult matter to write a
subroutine using LEN, MID$, ASC and a FOR—NEXT loop to display a
string of any length in inverse rather than normal mode — try it.
74 Advanced graphics
Finally, two more for the road. ‘SPLIT CIRCLE’ differs in two minor
but subtle respects from the version in the Oric manual. ‘CREEPING
REVERSAL’ is so painfully slow in operation that it cries out to be
rewritten in machine code. However, with patience, the result is quite
interesting.
5 REM SPLIT CIRCLE
HIRES
FORN=41060T048979STEF40
POKEN, INT(RND(1)*7) +16
POKEN-19, INT (RND(1)%7) +1
NEXT
CURSET120,100,3
FORX=95TO1STEF-1
CIRCLEX,2
NEXT
190 WAIT200
110 TEXT
120 LIST
10 REM CREEFING REVERSAL
20 REM TO RECOVER, RUN AGAIN
30 REM OR RESET
90 P=#BR400
100 FOR I=49TO090:FRINT CHR#(1) 32 NEXT
110 FOR S=F+8%*49 TO F+8x90 STEF 8
20 FOR R=0OTO6
130 Y=PEER (S+R)
140 FORZ=1T05
150 Q=2°Z
160 P=Y AND Q
170 IF F=0 THEN B=0 ELSE B=2"(6-Z)
180 C=C OR B
190 NEXT
200 POKE S+R,C
210 C=0
220 NEXT: NEXT
The Sound of (Oric) Music
Oric’s sound department is very advanced; a distinct improvement
over the very limited facilities found in other popular machines. This
is thanks to the inclusion of a special sound-generator IC which looks
after most of the business of generating the sounds. Thus the micro-
processor itself (the ‘brain’ of the Oric) only has to send commands as
to the sort of sound(s) that it wants; the sound generator looks after it
all from there on, freeing the rest of the machine for other purposes.
However, we are faced with the usual trade-off. The great versatil-
ity of the sound department necessarily implies a fair number of things
to remember in order to get the exact effect you want. Most of these
are covered in the following examples or in the examples in the Oric
manual. But you can always verify any particular point for yourself,
with a few moments experimenting — or ‘composing’ — at the
keyboard.
The predefined sounds PING, ZAP, SHOOT and EXPLODE are all
quite straightforward and their use is covered in the manual. To
produce more musical noises, one uses SOUND, MUSIC, PLAY,
with parameters to control pitch, volume, etc. as appropriate. A
useful feature of these commands is that Oric automatically takes the
integral part (whole number) of all parameters. Thus in the manual’s
‘MUSIC?’ program, in line 20 for example, RND(1)*6 may call up
octave 2.64329765, say, but this will simply be taken as octave 2.
Just how the program works will become clear later in this chapter,
when we look at the MUSIC command in more detail.
In the manual’s ‘KEYBOARD’ program, note that A$ in line 60
should be ‘\’, reverse slash, and that line 30 should read
30 A = VAL(A$)
Unfortunately, one cannot play a complete scale on the top row of
keys, as the octave is missing. ‘FULL OCTAVE KEYBOARD’ below
75
76 The Sound of (Oric) Music
remedies this; ‘\’ now plays the octave of ‘1’, so you can practise your
scales and arpeggios to your heart’s content. To stop the sound, press
se
10 REM FULL OCTAVE KEYBOARD
200 =3
30 GET A$: A = VAL (A$)
40 IFA$ = “’—"" THEN A = 11
50 IFA$ = “=” THEN A = 12
60 IFA$ = ‘’]’” THEN PLAY 0,0,0,0: STOP
70 IFA$ = 0" THEN A = 10
75 IFA$ = “\" THEN A = 1:0 = 4
80 MUSIC 1, O,A,5
90 GOTO 20
The MUSIC command
Now let’s look in detail at the command MUSIC. Channel, Octave,
Note and Volume are four parameters which must be entered in that
order, separated by commas, following the command MUSIC. Thus,
MUSIC 1,3,1,15 will play the same note as middle C ona piano. Oric
is at ‘concert pitch’, so if yours is an old piano, it may be a little flat
relative to Oric. MUSIC 1,4,1,15 will play the octave above middle C
and MUSIC 1,4,8,15 the G above that, etc.
Note the fundamental difference between MUSIC Channel 1 and
MUSIC Channels 2 and 3. On MUSIC Channel 1, if a volume level in
the range 1 to 15 is entered, the note will start to sound as soon as
RETURN is pressed in immediate mode: try
MUSIC 1,3,1,7 RETURN
Similarly, in a program, the note will sound as soon as program
execution reaches the MUSIC 1,3,1,7 statement, provided a PLAY
0,0,0,0 command has not been executed earlier in the program. The
volume level will be as set by the volume parameter; 7 in this case. If,
however, 0 is entered as the volume parameter, then the note will not
sound until a PLAY command is entered. Try
MUSIC 1,3,1,0:WAIT 200: PRINT “NOW”: PLAY 1,0,7,200 RETURN
Don’t worry about PLAY parameters, we will look at those in a
minute. The point of interest at the moment is that MUSIC Channels 2
and 3 are different from CHANNEL 1:
MUSIC 2,3,1,7 RETURN
The Sound of (Oric) Music 77
will produce silence. However, add
:PLAY 2,0,7,1
before pressing RETURN and the note will sound. Likewise, MUSIC
Channels 2 and 3 in a program will not sound until an appropriate
succeeding PLAY command is encountered, even though VOLUME
is not set to O.
In immediate mode, pressing any key will terminate any note(s)
which are sounding. (This is because of the key click routine, so it
does not work if the key click is turned off with CTRL F.) This fact and
the use of Channel 1 result in the very simple programming for
monophonic (one note at a time) music, as exemplified by the
KEYBOARD program in the manual.
The PLAY command
All three MUSIC Channels behave similarly when Volume is set to 0,
and this brings us to the PLAY command. This needs the four
parameters: Tone Enable, Noise Enable, Envelope Mode and
Envelope Period. To see how they work, try running
10 MUSIC 3,3,1,0:PLAY 3,0,1,2000
Sounds all right? Well, the note specified by the MUSIC command is
middle C, whereas (if you’re musical) you will have noticed that a
different note was played. This is because the first PLAY parameter,
Tone Enable, is inappropriate. Reference to the manual shows that
PLAY 3,0,1,2000 enables Channels 1 and 2. Change it to PLAY
4,0,1,2000 (enables Channel 3) and will be well.
The second parameter of PLAY is Noise Enable. If this is set to zero,
the note defined by MUSIC will be played as a pure tone, with no
added noise. If the second parameter is not 0, then noise will be
added to the note. The larger the number, the quieter the note relative
to the noise, or so it appears, but some experimentation may be
required. A number larger than 65535 or a negative number will
cause an error message. For most purposes, O or 1 (for pure tone or
tone plus noise respectively) will suffice.
Envelope Mode and Envelope Period act together to determine the
type of sound produced. The envelope will be as described in the
manual, provided the MUSIC command to which the PLAY refers has
its Volume parameter entered as 0. Thus
MUSIC 2,3,1,0: PLAY 2,0,1,3000
78 The Sound of (Oric) Music
will result in a pleasant ‘bong’, though one has no control over the
volume.
MUSIC 2,3,1,0: PLAY 2,0,1,1000
will result in a much briefer bong.
If the Volume parameter of MUSIC is not 0, following PLAY the
tone will go on sounding at the level set by the Volume parameter of
MUSIC. However, the start-up of the sound will be modified by the
Envelope Mode of PLAY. So Envelope Modes 1 and 2 are not useful
unless Volume is set to 0, but Mode 7 in particular is useful if Envelope
Period is kept very short. This is an important point to note, as it
enables one to select the Volume with MUSIC but still control when
the note sounds with PLAY.
SOUND works rather like MUSIC, in that SOUND Channel 1 will
sound immediately without any following PLAY command if the
Volume is not set to zero. Channels 2 and 3 will only sound when
called up by an appropriate following PLAY. Channel 4,5 or 6 can be
invoked to add noise to the SOUND channel. Since noise has no
pitch, the Period parameter is irrelevant, but a dummy number must
be entered.
The useful feature of SOUND is that it is not restricted to the notes
of the scale like MUSIC. You can thus program gliding tones. Thus, in
a video game, you could at any time call up a bomb dropping quite
simply with GOSUB 1000:
1000 PLAY 1,0,1,1: FOR X = 1 TO 200:SOUND
1,X,15: NEXT: EXPLODE:
WAIT 99: RETURN
This will all fit in one program line if you use no spaces. Though
very effective, from the point of view of legible programming it is just
about as horrible a one-liner as you will find in a good while. Note
that internally the EXPLODE routine ends with a PLAY 0,0,0,0, so the
PLAY 1,0,1,1 is necessary. Otherwise the subroutine will only work
properly the first time it is called in a program — try it!
Using the sound facilities
Having looked at how the various sound commands work, let's put
them to use. The programs that follow are designed to illustrate
various points about using the sound commands.
First, envelope control. One seems with PLAY to have the choice
of a sharp attack and a slow decay (Envelope Mode 1) or a slow attack
The Sound of (Oric) Music 79
and a fast decay (Mode 2, or Mode 7 followed by a WAIT and a PLAY
0,0,0,0.). In fact, you can have both gentle attack and slow decay
thus:
100 MUSIC 1,3,1,0:PLAY 1,0,7,500
120 WAIT 50: PLAY 1,0,1,5000
Of course, you don’t have to write all this out for every note. In
practice you would write it as a subroutine and pass parameters to it
as appropriate:
100 MUSIC C,O,N,0:PLAY CP,0,7,500
110 WAIT L: PLAY 1,0,1,5000
120 RETURN
where you set C = 1, 2 or 3 (whichever Channel you wish to use), CP
= C(or CP = 4 ifC = 3), O = to the required Octave, N to Note andL
to Length, before jumping to line 100 with a GOSUB. The program
would then set up the parameters for the next note (perhaps READing
them from a DATA statement) while the current note is sounding.
Here is a little subroutine which shows how one can play about
with envelopes and volume levels.
1 REM MUSIC DEMO 1
5 FORX=1TO5 STEP 2
10 MUSIC 1,3,X,0: PLAY 1,0,7,10
20 WAIT 15: MUSIC 1,3,X,11:WAIT 10
30 FOR N = 7TO1 STEP — 1
40 WAIT 5: MUSIC 1,3,X,N: NEXT
50 PLAY 0,0,0,0
60 NEXT
Here is a demonstration of passing parameters to a NOTE/PLAY
subroutine. Parameter B is Octave and C is Note. As it happens, the
tune stays within one octave, so B is set to 3 throughout the DATA
statement, but with a wider ranging tune it would change as appro-
priate. To transpose the tune up or down an octave, one can process
B in the subroutine starting at line 100:
105 MUSIC A,B + 1,C,0 etc.
will transpose up one octave. It is not much more difficult to arrange
transposition to other keys.
5 REM FRERE JACQUES DEMO
10 A=2:D=2
80 The Sound of (Oric) Music
20 FORI=1TO14: READ B,C
30 GOSUB 100
40 NEXT
50 DATA 3,1,3,3,3,5,3,1,3,1,3,3,3,5,3,1,3,5,3,6,3,8,3,5,3,6,3,8
80 END
100 IF | = 11 THEN T = 80 ELSE T = 30
105 MUSIC A,B,C,0:PLAY D,0,7,5:WAIT 10
110 PLAY A,0,1,3000: WALT tT: RETURN
Finally, here are a couple of longer, more ambitious programs. The
first is an original composition. It will never make the top twenty,
though with luck it might make the top ten thousand. The program
illustrates again the passing of parameters to a subroutine. It also
illustrates how a program without copious REMarks is fairly impene-
trable. | wrote it a few weeks before writing the chapter and it would
take me a good while to fathom it out again now.
S CLS:PRINT
PRINT"? Harmonies du soir’ Op.1, No.1"
PRINT
PRINT" A Lullaby"
PRINT
PRINT" Tan Hickman ";CHR# (96) 3"1983"
PRINT
PRINT": (Playing time 4 1/2 mins)"
PRINT
V=3:S=10
IFX/2=INT (X/2) THENQ=SELSEOQ=4
PRINTX3Q;S
L=1:M=Q:N=8
GOSUBS10
L=1:M=6:N=9
GOSUB310
L=1:M=0:N=8
GOSUB310
O L=i:M=3:N=6: Z=1
GOSUB310
MUSIC1,V,12,S
PLAY7,0,7,1
WAIT200
PLAYO,0,0,0
Z=0:WAIT4O
L=1:M=Q:N=8
GOSUB310
X=X+1:WAIT4O
IFX/2¢ > INT (X/2) THEN208
V=V+1: IFV=STHENV=3
S=INT(10-X) : IFS=OTHEN220
GOTO20
CLS: FORE=1T01i8
READF
PLOTE, 10, CHR& (F)
NEXT
The Sound of (Oric) Music 81
260 DATA32,87,97,115,110, 39, 116, 32, 116, 104,97. 116,
32,110,105,99,101,63
270 END
310 MUSIC1,V,L,S
320 MUSIC2,V,M,S
330 MUSIC3,V,N,S
840 PLAY1,0,7,1
850 WAIT1OO
B60 PLAYS,0,7,1
870 WAIT100
880 PLAY7,0,7,1
890 WAIT100
895 IFZ=1THENRETURN
900 MUSIC1,V+1,1,S
910 PLAY7,0,7,1
920 WAIT210
930 PLAYO,O0,0,0
940 WAIT4O
950 RETURN
Here’s another masterpiece, the Moonlight Sonata. To be precise,
it is the opening of the first movement, arranged as a moto perpetuo.
When you've had enough, CONTROL C will come to the rescue!
S CLS:PRINT
10 FRINT" SONATA in C sharp minor":FRINT
20 PRINT" (Sonata quasi una Fantasia) ":FRINT
30 PRINT" Ludwig van Beethoven, Op.27, Na.2":FRINT
40 PRINT" Bearbeitet von Ian Hickman"
SO REMV=OCTAVE, R=BASS, S=SUB-—BASS
60 REMU=RHAND UPPER OCTAVE,L=RH LOWER OCTAVE
70 Ves
8O B=V-1:S=V-2:L=V; U=V+1
99 A=2
200 MUSIC2,B,A,0
220 MUSIC1,L,9,0
230 PLAYS, 09,1, 5000
240 WAITSO
250 MUSIC1,U,2,0
260 PLAY1,0,1,5000
279 WAITSO
280 MUSIC1,U,5,0
290 PLAY1,9,1,5000
300 WAITSO
310 FORI=1T03
320 GOSUB1O00
330 NEXT
340 IFA=1THEN360
350 A=1:GOTO200
360 MUSIC2,S5,10,0
370 MUSIC1,L,19,0
380 PLAYS,0,1,5000
385 WAITSO
390 MUSIC1,U,2,0
400 PLAY1,0,1, 5000
82 The Sound of (Oric) Music
410 WAITSO
420 MUSIC1,U,5,0
430 PLAY1,0,1,5000
440 WAITSO
450 MUSIC1,L,10,0
460 PLAY1,0,1,5000
470 WAITSO
480 MUSIC1,U,2,0
490 PLAY1,9,1, 5000
Soo WAITSO
S10 MUSIC1,U,5,0
S20 PLAY1,0,1,5000
S30 WAITSO
540 MUSIC2,5,7,0
S50 MUSIC1,L,10,0
S60 PLAYS, 0, 1, 5000
570 WAITSO
S80 MUSIC1,U,3,0
S9O PLAY1,9,1,5000
600 WAITSO
610 MUSIC1,U,7,0
620 PLAY1,0,1, 5000
630 WAITSO
640 MUSIC1,L,19,0
650 PLAY1,0,1, 5000
660 WAITSO
670 MUSIC1,U,3,0
680 PLAY1,0,1, 5000
690 WAITSO
700 MUSIC1,U,7,0
7190 PLAY1,0,1,5000
720 WAITSO
730 MUSIC1,L,9,OsMUSIC2,S,.9,0
740 PLAYS,0,1, 5000: WAITSO
750 FORI=1TOS: GOSUB2Z000
760 NEXT
770 MUSIC1,L,9,O:MUSIC2,$,9,0
780 PLAYS, 0,1, 5000: WAITSO
790 FORI=1 TOS: GOSUB2Z000
800 NEXT
810 MUSIC2,S,9,O:MUSIC3,B,2,0:MUSIC1I,L,5,0
820 PLAY7, 9,1, 5000:WAITSO
830 FORI=1T02: GOSUB2Z000
840 NEXT: RESTORE
850 A=2:GOTO310
1000 MUSIC1,L,9,9
1010 PLAY1,0,1, 5000
1020 WAITSO
1030 MUSIC1,U,2,0
1040 PLAY1,9,1,5000
1950 WAITSO
1060 MUSIC1,U,5,0
1070 FLAY1,9O,1,5000
1080 WAITSO
1090 RETURN
2000 READN,M:MUSIC1,N,M,0
2010 PLAY1,O,1, 5000; WAITSO: RETURN
BOBO DATA4s 144475 3a Fn Fa By Fy ey Bu Fn de By 7a 4a de 4a 4e
3,9,4,2
Saving programs on tape
The saving and loading of programs is very straightforward, as is
apparent from the manual, and once you have done it a few times
you will have memorised the format and you won’t need to consult
the manual each time. You will find it saves a great deal of time if you
habitually use the fast (2400 baud) recording format; Oric will
automatically select this for both saving and loading unless you
instruct otherwise. For example
CSAVE’’NEWGAME”
will save at 2400 baud, while
CSAVE“NEWGAME”,S
will save at the Slower speed of 300 baud. However, you may find,
especially with long programs, that after loading at normal speed they
won't run properly or may even crash completely. If just one byte is
loaded wrongly this can easily happen, although if the error is in a
little-used subroutine, the program may run correctly most of the time
and then crash quite unexpectedly.
Hardware
Is there any way round this or must one resign oneself to using the
deadly slow (but safe) 300 baud? This depends on how good your
recorder is and how good are the cassettes you use with it. | use a
small portable mains-driven mono cassette recorder with automatic
level control. This machine (actually a Trophy CR100) has the facility
for recording on and playing from either standard ferric and super
ferric cassettes or the slightly more expensive but higher quality CR
83
84 Saving programs on tape
(chrome dioxide) cassettes. These latter differ from ordinary cassettes
not only in the material of the oxide coating on the tape (it’s greyish
black rather than brown) but also in having a depression in the
cassette next to the record protect tab. The recorder’s mechanism has
a finger which detects this depression when a chrome cassette is used
and automatically selects the appropriate mode of operation —
chrome tapes need different bias and equalisation settings from ferric
tapes.
Most programs offered for sale on cassette will, for cheapness, be
recorded on ferric tape. Often the program will be recorded on the
tape at both 300 baud and 2400 baud — belt and braces. | have such
a tape and found that it would load satisfactorily at 300 baud but not
at 2400 baud. As the loaded program occupies over 6K of memory,
loading at 300 baud takes the best part of 10 minutes! The solution
was to load at 300 baud and then save at 2400 baud on to a chrome
dioxide cassette. The latter loads the program quite reliably in around
a minute: a big improvement.
If, in a given application, Oric is intermittently producing output or
results which you wish stored on cassette, it is not necessary to have
the recorder running continuously. If it did, it would use up recording
space on tape unnecessarily. Note that pins 6 and 7 of the 7-way DIN
socket which forms the cassette/sound interface are connected to a
relay inside Oric. These contacts close just before output is sent from
Oric to cassette, to allow the cassette deck to get up to speed for a
CSAVE operation. Likewise, they close during a CLOAD read opera-
tion. The relay contacts are entirely isolated electrically from Oric’s
internal circuitry and may be used to control the motor of a cassette
deck.
The type of mono cassette recorder which has a switch incorpo-
rated in the microphone (so that it can be used as a dictating machine)
is very convenient for this purpose. A length of lightweight twisted
flex should be connected to pins 6 and 7 of the DIN plug mating with
the Oric’s cassette/sound socket. The other end of the flex should be
connected to a 2.5 mm miniature jack plug (it doesn’t matter which
wire goes to the inner contact of the plug), which is then plugged in to
the REMOTE socket next to the 3.5 mm MIKE socket on the recorder.
Now, once you have set the cassette recorder to RECORD (or PLAY,
as required), the motor will be turned on by Oric whenever it wants to
record (or play) and turned off in between times.
How and when to SAVE
Having covered the mechanics of recording, here are some tips on
how and when to SAVE. First, even if you use 300 baud, you will find
Saving programs on tape 85
that recording a program takes much less time than writing it. So,
when you have written a program and are itching to try it out, don’t
run it. SAVE it first, then run it. If it crashes, you can reset the
computer, reload the program and start looking for the fault— see the
tips on debugging in Chapter 5.
In fact, you will usually want to try the program as far as it goes each
time you have just completed adding a new section. The rule is the
same: SAVE the latest version before you run it. There is no need to
save all the previous versions as well, just save the current version at
the same starting point on the tape each time, thus overwriting the
earlier version. This is where a digital tape position indicator is invalu-
able; it is virtually a necessity.
Unfortunately, although the Oric has several program recording
modes, there is no ‘APPEND’ or ‘MERGE’ facility. The latter, found
on some other machines, allows one to load a second program from
cassette ‘on top’ of a program already resident in the computer. On
the Oric, the CLOAD command executes a ‘NEW’ instruction,
effectively destroying any program currently in the computer. One
could in theory load a second program on top of one already in the
machine by using
CLOAD “”",AXXXX,EYYYY
assuming the second program had previously been saved in that
form. However, unfortunately it will not work, for reasons which are
explained in the chapter on machine code programming. Neverthe-
less, before long someone will come up with a way round the prob-
lem, so look out for it in Oric Owner or one of the general personal
computing magazines.
Here’s a scheme which works for adding a short chunk of BASIC,
let’s call it section B, to another program, say section A.Load section
B from cassette and LIST it on the screen. Then, taking care to keep
the cursor away from the bottom two lines, load section A. This will
automatically delete section B, but you still have it listed on the
screen. So you can now tack it onto section A with the CONTROL A
editing facility. You can use ‘SCREEN SWAP’, relocated to address
#400 (see Chapter 13), to store program in ‘SPARE’ screen as well, to
provide extra ‘screen’ storage space. A more ambitious scheme for
merging programs is outlined in Chapter 13.
Finally, it can be useful to be able to store an array, either a string
array Or anumeric one. Issue 2 of Oric Owner contains a routine that
lets you do just this.
12
Better BASIC
Writing good BASIC programs is largely a matter of practice but there
are in addition numerous tips which can help one develop a good
‘style’. Some of these are presented here and you will pick up others
from fellow home computerists and the various magazines devoted
to personal computing. In particular watch out for useful published
programs specifically written for the Oric. These started to appear
soon after Oric hit the market and many more will follow.
Flowcharts and ‘structure’
For the professional programmer there are dos and don'ts, often laid
down as company policy by his or her employer. ‘Structured
programming’ is a favourite — this means dividing the software up
into neatly partitioned sub-units, each with unique entry and exit
points. The logic behind this is that each sub-unit or package can be
written by a different programmer working in (relative) isolation from
the others. Hence a program needing several man-years of effort can
be written in months by a team of programmers working in
parallel. (Well, that’s the theory, anyway!) In such a software house,
BASIC would not figure at all, being considered far too primitive a
language.
For the home computerist, the rules are completely different. For a
start, he or she is programming as a hobby or pastime, not as a job,
and generally no other programmers are involved. Nevertheless, one
should aim to produce neat, well-constructed programs liberally
supplied with REMarks. After all, three months later you may wish to
modify a program. If it was not well documented in the first place,
you may find it takes you a long time to figure out again how it works.
Another reason for turning out neat programs is that they may well
86
Better BASIC 87
prove saleable. The many magazines covering home computing are
always on the look-out for useful or interesting programs for any of
the popular makes of computer such as the Oric and they pay for
contributions published.
So how do we write good programs? In the first place, by taking the
trouble to define at the outset just what we are trying to do and how
we intend to do it. For anything other than the simplest of programs, a
flowchart can be a real help here. Indenting the final program, as in
the manual’s example CURVE STITCHING, improves its clarity,
especially where there are simple nested loops, but this is rather an
after-the-event measure. The flow diagram of Fig 3.3 illustrates the
operation of the ‘Noughts and Crosses’ program of Chapter 3 in a
way that no amount of indenting can do. Figure 12.1 is typical of a
flowchart for amore ambitious program. It looks relatively simple and
uncluttered only because certain lines have been omitted, their desti-
nations being indicated by circled letters.
Having decided on the program plan, in the form of a flowchart if
appropriate, the various sections can be written. Program line
numbers should advance in tens, starting at, say, 100 or even 1000. It
is a good idea to put any REMarks on a separate line, with the line
number ending with a 5, e.g.
410 CLS
415 REM SET PRINTOUT LOOP
420 FORN = 0 TOD
430 PRINT A$(N)
and so on.
It does not matter much whether you always put a REM on the line
following that to which it refers or, as here, on the line preceding it,
but you should standardise on one or the other and be consistent.
We shall see in the next chapter that spaces in program lines (FOR
K = STO Pis clearer than FORK = STOP) and REMs occupy quite a
lot of memory space and slow down program execution. You may
therefore wish to keep a fully REMarked and spaced program on tape
as a master back-up while producing a REM and space-free program
for actual running. It is possible to write a program which will comb
through an existing program and delete all lines with line numbers
ending in 5 and delete all spaces not within quotes in the remaining
lines; for a small program the same can be done quite quickly using
Oric’s editing facilities. So never GOSUB or GOTO a REM line
number; go to the program line to which the REMark refers.
It was pointed out earlier that in Oric BASIC the INPUT statement
will automatically call up a screen message, thus:
950 INPUT “HOW MANY ENTRIES”; E
88 Better BASIC
y)
b-{5
¢
5
4
Inc. mark
Ea
<>
Space
‘Add space to
MARK.
Add mark SPACE = 00
to SPACE
MARK = 00
Inc, mark
rey ee
Ea)
(°)
Figure 12.1 A typical flowchart. It represents a program to decode signals in
Morse code to plain text (reproduced by courtesy of Wireless World)
Better BASIC 89
will result in
HOW MANY ENTRIES?
with the cursor waiting on the same line for an input. The question
mark will be placed there automatically by BASIC whether there be a
message or not, so if you include a message it should be in the form of
a question rather than a statement, to avoid something like
STATE NO. OF ENTRIES?
If you precede an INPUT with a PRINT CHR$(7) thus:
950 PRINT CHR$(7): INPUT’; HOW MANY ENTRIES” ;E
then a request for input will be accompanied by a PING. If only a very
occasional input is required, so that the operator may be away
making tea, the PING can be repeated at one-second intervals until
the required input is forthcoming.
950 CLS: PRINT’ HOW MANY ENTRIES?”
960 PRINT CHR$(7)
970 A$ = KEY$: IF A$ = “”” THEN WAIT 99:GOTO 950
980 INPUT“ HOW MANY ENTRIES” ;E
Note that in line 970 the two sets of inverted commas are in adjacent
letter spaces; they enclose nothing, not even a space. On pressing
any key, that key press will be ignored but a second HOW MANY
ENTRIES? will be printed by line 980 and the INPUT statement will
then wait for input.
Portability and the Oric
One consideration you should bear in mind when programming is
whether your program is going to be specific to the Oric or portable.
Portability implies that the program will (or should) run on any
personal computer which operates in BASIC. True portability is
virtually impossible, as the facilities on different machines vary so
much. Obviously if a program is to be fairly portable one should
avoid PEEKing and POKEing to specific locations in RAM, such as
current cursor position, as these will certainly differ from one
machine to another. Likewise, Oric’s HIRES screen and also the
PLOT command in TEXT/LORES (similar to PRINT AT on some
personal computers) are not available on many other machines. An
90 Better BASIC
example of a program designed to be as portable as possible is
Noughts and Crosses in Chapter 3.
Most personal computers using the 6502 processor IC (Oric,
Apple, Pet, etc.) use Microsoft BASIC. (Microsoft is the name of a
famous American software house which has produced probably
more implementations of BASIC for personal computers than any
other software company.) The various dialects of Microsoft BASIC for
the 6502 all are very similar, so it is easier to achieve program port-
ability between these machines.
However, returning to programming specifically for the Oric, here
is a useful tip for use when developing graphics sequences using the
HIRES screen. Having developed the program to a particular point,
you will need to run it to check that it operates as intended. You will
then need to return to the program to modify it or write the next
section. This is conveniently achieved without any effort by including
a final line in the program as follows:
60000 WAIT 200: TEXT: LIST
This will provide a couple of seconds’ viewing time of the state of play
at the end of program execution before relisting the program ready for
further work.
If the program is lengthy, further time can be saved by listing only
the last few lines. Just qualify LIST thus:
LIST 7530—
This will list from line 7530 (or whatever) to the end of the program. If
working on lines M to N then use
60000 WAIT 200: TEXT: LIST M—N
As on a typewriter, the minus sign does double duty as a hyphen as
well.
Boolean operations
A word about bit manipulation and Boolean operations. (If you have
not read Chapter 7, then skip this section for now.) Like other
Microsoft BASICs, Oric BASIC includes Boolean and bit manipula-
tion facilities, not covered in the manual. Let’s look at Boolean
expressions first. These use the operators > (greater than), < (less
than), equals, AND, OR, NOT in various combinations. Boolean
expressions are given a numerical value by Oric BASIC, according to
Better BASIC 91
whether they are true or false. You may not realise it, but you have
used such expressions already, as they form the basis of ORIC’s
IF-THEN-ELSE decision making. For instance, try
10A =5:B=6
20 IF A < B THEN PRINT “A<B” ELSE PRINT “B<=A”
This, when run, will print A << B, but change A in line 10 to 7 and
you will get B < = A (B is less than or equal to A). Oric decides
whether the expression A<B is true or false, for the given values of A
and B, and acts accordingly. It actually allocates a value to the
expression A < B; the value —1 if the expression is true or zero if it is
false. Thus the expression X = (A = 5 ANDA < > 5) results ina value
of zero for X since the expression in the brackets is false, whatever the
value of A. Similarly, X = (B = 2*B — B) will give X the value of —1
indicating true. Thus
PRINT 27* (B = 2* B — B)
will give
—27
The value zero for false is unique, but in practice, as well as —1,
Oric will accept any non-zero value as indicating true. Try
10 FORA=-5TO5
20 IF A> <0 THEN PRINT “TRUE” ELSE PRINT ‘/FALSE”
30 NEXT
This will print
TRUE
TRUE
TRUE
TRUE
TRUE
FALSE
TRUE
TRUE
TRUE
TRUE
TRUE
because at each stage A is compared with zero and the expression
evaluated as —1 if true and 0 if false. However, in place of —1 we
92 Better BASIC
could as well have —5 or +5 or anything but 0 and ORIC would still
regard the inequality in line 20 as true. Consequently, when you need
to test for a non-zero result, instead of using IF X < >0 THEN... . you
can simply use IF X THEN . . .. If you don’t believe it, try IF A THEN
PRINT... in line 20!
The logic terms AND, OR, NOT may be used for bit manipulation
in Boolean operations on double-byte numbers, i.e. 16-bit binary
numbers, sometimes called ‘words’. The 16-bit numbers are treated
as two’s complement numbers; thus if the MSB (most significant bit) is
zero the number is positive and in the range 0 to 32767, while if itis 1
the number is between — 32768 and —1 inclusive. The AND, OR and
NOT operators apply to corresponding bits in the two numbers being
compared. Thus 63 AND 17 = 17 since the result only has ones in
those bits which are at 1 in both of the numbers:
MS byte LS Byte
First number 0000 0000 0011 1111 63
Second number 0000 0000 0001 0001 17
Result 0000 0000 0001 0001 17
Similarly, if you try it out, either on paper or on Oric, you will find
that
—1AND4=4
4OR2=6
11OR11 = 11
NOT0= -1
NOT1 = —2 etc.
Remember that for each and every individual bit in the number NOT
0 =1 and NOT 1 =0.
Thus for the complete 16-bit number:
NOT 0 decimal = NOT 0000 0000 0000 0000 binary
~ 1111 1111 1111 1111 binary = —1 decimal
since we are not using straight binary, but two’s complement. (If we
were using straight binary, NOT 0 would equal 65535. However, we
would have no means of representing negative numbers. Two’s
complement notation is covered in Chapter 7.)
Using bit testing, we can test whether a number or variable is odd
or even much more elegantly than the rather clumsy
IF X/2 = INT(X/2) THEN ...
In logical expressions involving AND, OR, NOT, variables are
assumed to be two-byte two’s complement numbers between
Better BASIC 93
—32768 and 32767, so this test will only work for numbers within
that range. However, any fractional part is ignored. The simple test,
then, consists of ANDing the variable or number with unity, so try
IF X AND 1 THEN PRINT “ODD” ELSE PRINT “EVEN”
with various values of X, such as 10, 99, PI, SQR(17), —1234, etc.
13
Machine code
Half a dozen or so different microprocessors are used in various
makes of personal computer, notably the 6502 (MOS Technology),
the Z80 (Zilog), the 8080 and its derivatives (Intel and the 6800 and its
derivatives (Motorola). Each has its own architecture and instruction
set, and for each whole books are devoted to the topic of machine
code programming.
It has been explained earlier how the computer's native tongue is
machine code, but that a BASIC interpreter, held in ROM, makes the
machine more friendly by communicating in conventional
mathematical and English-like terms. The price paid for this useful
facility is slow program execution, but since ‘slow’ is a relative term,
and computations are usually complete in the twinkling of an eye, this
usually does not matter. However, there is built into your computer
the ability to operate 100 or more times faster when the program is
written in machine code rather than BASIC, so it is worth trying your
hand at machine code programming out of interest. It also comes in
handy in a number of practical applications; for example, comput-
erised music.
Op-codes
So how do we program in machine code? In detail, that depends on
which microprocessor we are talking about, or which ‘assembler’ we
are using; for machine code programming can be carried out at two
quite different levels. (What an assembler is and what it does is
explained shortly.) At the grass roots level, we would enter particular
op-codes and numerical data at successive memory addresses. An
op-code (operation code) is a two-digit number. The digits are hex, in
which, as already explained, each digit represents a number in the
94
Machine code 95
range 0 to 15, so that instead of 10 we write A, and so on up to F for
15. Thus the left-hand (most significant digit) is in the 16s column
rather than the 10s column. Hence the highest number that can be
represented by two hex digits is FF, i.e. (15 X 16) + 15 = 255, as
against 9 X 10 + 9 = 99 in decimal. (You will recall that one hex digit
represents four binary digits, so that two hex digits represent eight bits
or one byte.) Thus the maximum possible number of different
op-codes available to an eight-bit microprocessor is 255. Sixteen-bit
microprocessors have been available for some time and 32-bit
models are becoming available, but most personal computers use
eight-bit micros.
INSTRUCTION SET — ALPHABETIC SEQUENCE
ADC Add Memory to Accumulator with Carry Load Accumulator with Memory
AND "AND" Memory with Accumulator Load Index X with Memory
ASL Shift left One Bit (Memory or Accumulator) Load Index Y with Memory
Shift One Bit Right (Memory or Accumulator)
BCC Branch on Carry Clear
BCS Branch on Carry Set No Operation
BEQ Branch on Result Zero
BIT Test Bits in Memory with Accumulator OR Memory with Accumulator
BMI Branch on Result Minus
BNE Branch on Result not Zero Push Accumulator on Stack
BPL Branch on Result Plus Push Processor Status on Stack
BRK Force Break Pull Accumulator trom Stack
BVC Branch on Overflow Clear Pull Processor Status from Stack
BVS_ Branch or. Overflow Set
Rotate One Bit Left (Memory or Accumulator)
CLC Clear Carry Flag Rotate One Bit Right (Memory or Accumulator)
CLO Clear Decimal Mode Return from Interrupt
CLI Clear Interrupt Disable Bit Return trom Subroutine
CLV Clear Overflow Flag
CMP Compare Memory and Accumulator Subtract Memory from Accumulator with Borrow
CPX Compare Memory and Index X Set Carry Flag
CPY Compare Memory and Index Y Set Decmal Mode
DEC Decrement Memory by One Set Interrupt Disable Status
DEX Decrement Index X by One Store Accumulator in Memory
DEY Decrement Index Y by One Store Index X in Memory
Store Index Y in Memory
EOR “Exclusive-or Memory with Accumulator
Transfer Accumulator to Index X
INC Increment Memory by One Transter Accumulator to Index Y
INX Increment Index X by One Transter Stack Pointer to Index X
INY Increment Index Y by One Transfer Index X to Accumulator
Transter Index X to Stack Pointer
JMP Jump to New Location Transfer Index Y to Accumulator
JSR Jump to New Location Saving Return Address.
Figure 13.2 The mnemonics for the 6502 MPU instruction codes
Notall of the 255 different op-codes are used, though some micros
use more than others. Figure 13.1 shows the op-code set for the
6502, which is used in the Oric. Next to each valid op-code is shown
a group of three letters; these are known as the mnemonics, and
Figure 13.2 translates these into English. As one example is worth a
thousand words, let’s look at an extremely simple and short program
in machine code and see how it works.
96 Machine code
(MPLIED ACCUM ABSOLUTE | ZERO PAGE IMMEDIATE
2D 3 3 ; 2/40) 4 3
OE 3 5 le} 7] 3
pod eT
(
>
oO
fo}
18
=
cD cS
£C £4
CC c4
vn
On<xo]<xv<-foovoztrm-apfvoro
zommnmlvverrirnr<<xnJvze-moounz
L8&
c8
NN
4c
20
AD.
fs | 8s]
:
TN
IN
JM 313
Js 6] 3
Lo 4] 3 Jas] 3] 2 3
Lo Ae] 4] 3 [Ae] 3 | 2 Jaz] 2] 2
Lo AC] 4] 3 [Aa] 3 | 2 | Aol 2 | 2 Jec] 4] 3
Ls 2 ae] 6] 3 }46]5 ] 2 se] 7] 3
NO
OR oo} 4 | 3 fos] 3 | 2 J oof 2] 2 Jip] 4 | 3
PH 48] 3
PH 08 3
PL 68} 4
Pit 28] 4
RO 2a | 2 2 3 5 [2 se] 743
i Aad : BEEBE :
RT 40] 6
RT 60] 6
SB to] 4] 3 Jes] 3 ] 2 2) 2];ro] a] 3
SE 38 | 2
SE Fa] 2
SE 78 2
st 8D 3 [85] 2 9D] 5 | 3
ST at 3 | 86] 2
st 3] 8a] 2
TA AAT 2
TA AB] 2
TS BA] 2
1x BA] 2
Tx 9A] 2
TY 98 | 2
(1) Add 1 to nif crossing page boundary
(2) Add 2 to nif branch within page, add 3 to nif branch to another page
OP Operation code
n - Number of machine cycles to execute the instruction
# Number of bytes of program occupied by the instruction
Thus, for exampie, ADD WITH CARRY Accumulator to Absolute Memory Location
(1e anywhere in 64K addressing range) 15. 6D LO HI, three bytes with two-byte address
in low, high order; it executes in four machine cycles, te in 4 microseconds as Oric
uses a 1MHz clock rate
Figure 13.1 Mnemonic codes and corresponding operation codes (op-codes) for the
6502 MPU. Note that most mnemonics correspond to various codes depending on the
type of addressing used (e.g. absolute, indexed, zero page, etc. — see Fig. 13.4)
Machine code 97
ABS Y (IND x) (IND)Y Z PAGE X RELATIVE | INDIRECT Z PAGE Y PROCESSOR
STATUS CODES
GBEGREERE GREER eOeeoeo ee
79 61 71
39 21 31 7 3
16 2
90} 2
Bo] 2
2
2
FO, 2] 2
M7M6, e
2
2
2
2
2
O
55
F6
pe Te |
© = Modified by result of last operation
0- Set to0
1+ Set tol
M7M6¢ ~ Set equal to bits 7 & 6 of memory location ‘M’ tested
98 Machine code
A simple machine code program
Imagine we have two binary numbers, each in the range 0 to 255
inclusive, stored in memory locations 0800 and 0801 hex (2048 and
2049 decimal), and we wish to add them together and store the result
in #0802. (In the Oric manual, # (pronounced ‘hash’) is used to
indicate a hex number. Most other personal computers use $ (dollar)
for this purpose. The habit dies hard and in the Oric Owner you will
find $ occasionally used instead of #.) Let us write the machine code
program to do this in a series of memory locations starting at #0400.
The first instruction will be stored at location #0400, and when we
have written the program and wish to run it, we do so by typing CALL
#0400 and then RETURN. The machine then runs the program,
starting at #0400, returning to BASIC with a READY message when it
has finished.
The first instruction tells the MPU to load the accumulator — its
main working register — with the number stored at location #0800;
this requires three bytes which are stored in successive locations thus:
Location Op-code Mnemonic Comment
or address
ordata
#0400 AD LDA LOAD ACCUMULATOR
ABSOLUTE
#0401 00
#0402 08
Several points here: AD is the op-code instructing the MPU to load
the accumulator from the following address; and the comment
ABSOLUTE indicates that the memory address holding the number to
be loaded into the accumulator is greater than 255. Of course, the
MPU can’t read comments (or even mnemonics) but its instruction
decode section recognises AD as indicating that a two-byte address
follows. A peculiarity of some MPUs, including the 6502, is that two-
byte addressses are entered low (least significant) byte first, followed
by the high byte. The 6502 regards memory as divided into ‘pages’,
page 0 extending from memory location #0000 to #00FF (0 to 255
decimal), page 1 from #0100 to #01FF (256—511) etc., up to page
255, #FFOO-#FFFF (65280-65535).LDA ZP (load accumulator zero
page) would require only a single-byte address to follow, and the op-
code would be A5 instead of AD.
Now we instruct the MPU to add the number stored in location
#0801 to the number in the accumulator. This will result in the
answer being stored back in the accumulator, overwriting the
number that was there:
Machine code 99
Location Op-code Mnemonic Comment
0403 6D ADC ADD WITH CARRY ABS
0404 01
0405 08
and now it only remains to store the answer in location #0802
0406 8D STA STORE ACCUM ABS
0407 02
0408 08
That is not quite all there is to say about it, however. For instance,
what will happen if the two eight-bit numbers add up to more than
#FF?2 In that case the number stored in location #0802 will be the
eight LSBs of the answer, and indeed the whole answer if the two
numbers total less than 256 decimal. If the correct answer were
greater than 255, then the ninth bit of the answer will be the 1 stored
Accumulator
Index register
Index register
Program counter
Stack pointer
Processor status reg ‘P’
Carry 1= true
Zero 1 = result zero
IRQ disable 1 = disable
Decimal mode 1 = true
BRK command 1 = BRK
Overflow 1 = true
Negative 1 = neg
Figure 13.3 The 6502 processor programming model
in the ‘C’ or Carry bit of the MPU status register (see Fig.13.3). The P
register (Processor Status Register, sometimes called the Flags
Register or just Flags) is an eight-bit register in the MPU that indicates
certain conditions, some of which (e.g. Carry, Zero, Negative) refer
directly to the result of the last instruction executed. The 6502 up-
100 Machine code
dates its P register after every operation, whether upon one of the
internal registers in the MPU itself or upon a data byte in the main
memory (RAM). We could arrange for our little machine code
program to examine the Carry bit in the P register and store it as the
LSB of the next location #0803; in fact it is a short step from there to
modifying the program to add several eight-bit numbers and produce
a 16-bit result, with #0803 holding the MS byte of the answer.
Now we have just seen how our addition could have left the Carry
bit of the P register set, and in fact we didn’t know that it wasn’t set
anyway, even before we ran our program. So a good rule to follow is
to include an instruction to the MPU to clear the Carry bit at the begin-
ning of the program. Another point is that the 6502, unlike most other
micros, is capable of operating in the decimal mode as well as in
straight binary. This useful feature, plus its wealth of indexed address-
ing modes, are the main reasons for its popularity, enabling a very
comprehensive and fast executing BASIC interpreter to be packed
into minimal ROM space.
In the decimal mode, the 6502 treats a byte not as an eight-bit
binary number but as two BCD (Binary Coded Decimal) numbers. It
produces an internal carry from bit 4 to bit 5 of the result if the sum of
the two least significant nibbles exceeds 9, and sets the P register
Carry flag if the overall sum exceeds 99.
Now, we set out to add two eight-bit binary numbers, so again it is
good practice at the start of our little program to ‘Clear Decimal
Mode’, in case it was left set by an earlier operation. Finally, having
stored the result of adding the two numbers, the program would
automatically continue blindly with the next instruction after 0408 —
but we haven't written any. The result in practice is that the machine
would try to interpret the contents of the following memory locations
as op-codes and data — unsuccessfully. One thing is certain, the
MPU would not return control to the keyboard, which would thus be
‘locked out’, or inoperative; our program has ‘crashed’. Never mind,
it has completed the required task and, for example, a RESET would
return control to the keyboard.
But there is a better way than this. We simply add, at the end of our
program, an RTS — return from subroutine.
Thus, if we add these useful amendments to our program, and
relocate it so that it still starts at #0400, we finish up with it looking
like this:
Line Location Code Mnemonic Comment
10 0400 18 CLC CLEAR CARRY
FLAG
20 0401 D8& CLD CLEAR DECIMAL
MODE
Machine code 101
30 0402 AD0008 LDA LOAD ACCUM
ABSOLUTE
40 0405 6D 0108 ADC ADD WITH
CARRY ABS
50 0408 8D 0208 STA STORE ACCUM
ABS
60 040B 60 RTS RETURN FROM
SUBROUTINE
Note the change of format: we have added arbitrary line numbers,
purely for our own convenience (the computer doesn’t use them),
and rearranged things so that a command (e.g. AD, load accumu-
lator absolute) and the appropriate address (in this case 0800 — see
line 30) are all on the same line. This is a useful saving in paper with no
real loss of clarity.
We can run this little machine code routine by entering CALL
#400. BASIC will cause the machine to execute the routine as a
subroutine call and, as we have placed an RTS at the end, it will
automatically return control to the BASIC command mode, after
executing the code, with the usual READY message.
Of course running the program is all very well, but it would have
paid us to enter specific numbers in locations #0800 and #0801
before doing so — say 22 and AB — so that afterwards we could
check that we really had finished up with CD in #0802. This is in fact
the only way we will know that the program has indeed executed as
expected, since the whole program will execute in 21 machine code
cycles (see Fig.13.1) — say 21 microseconds with the usual 1 MHz
clock rate. Machine code cycles are directly related to the clock rate
at which the system operates. Note that various instructions corres-
pond to different numbers of machine cycles, depending on the
number of ‘microcycles’ involved in their execution. This is some-
thing that we don’t normally need to worry about unless we are tailor-
ing a program to run at the fastest possible rate; it is all looked after by
the instruction decode and control sections of the MPU.
Writing and entering a machine code program
If you were working without an assembler, you would write a
program, such as the little routine shown above, by concentrating on
the mnemonic and comment columns as these describe what the
program is doing in terms one can understand. (Resist the temptation
to dive straight into op-codes!) That done, one would then translate
the mnemonics into op-codes and add memory locations of data and
results, etc. (specified in hex with low byte preceding high byte) as
appropriate. Next the memory locations where the code is to be
102 Machine code
stored would be entered in the location column, in high followed by
low byte form or in decimal. A line number column may be added for
clarity if required — always a good idea.
So far we have looked at only a few of the 6502’s instruction codes,
CLC, CLD, LDA, ADC, STA and JSR, to be precise. But before
looking at any more, it is as well to be clear as to the different nature of
these. Thus in some ways, CLC and CLD, and their twins SET
DECIMAL and SET CARRY (SED and SEC) are the simplest, in that
these are implied instructions needing no further definition. They
simply modify the Decimal and Carry flags of the P register, and in the
case of CLD and SED change the mode of operation from binary to
decimal or vice versa. Instructions such as load accumulator LDA on
the other hand, can be absolute (meaning load from a two-byte
address, i.e. anywhere in the full 64K addressing range) or ZP (ZP or
zero page signifies a one-byte address, i.e. in the range 0 to 255
decimal), or immediate (load the byte stored in the program itself, in
the next instruction following the LDA instruction), or one of the
indexed modes of addressing. The 6502 MPU is particularly well
ADDRESSING MODES
ACCUMULATOR ADDRESSING — This form of addressing is represented with a one byte instruction, implying an operation
on the accumulator
IMMEDIATE ADDRESSING — In immediate addressing, the operand is contained in the second byte of the instruction, with
no further memory addressing required
ABSOLUTE ADDRESSING — In absolute addressing, the second byte of the instruction specifies the eight low order bits of
the effective address while the third byte specifies the eight high order bits. Thus, the absolute addressing mode allows
access to the entire 65K bytes of addressable memory.
ZERO PAGE ADDRESSING — The zero page instructions allow for shorter code and execution times by only fetching the
second byte of the instruction and assuming a zero high address byte. Careful use of the zero page can result in
significant increase in code efficiency
INDEXED ZERO PAGE ADDRESSING — (Xx, Y indexing) — This form of addressing is used in conjunction with the index
register and is referred to as “Zero Page, X" or “Zero Page, Y"'. The effective address is calculated by adding the second
byte to the contents of the index register. Since this is a form of “Zero Page" addressing, the content of the second byte
references a location in page zero. Additionally due to the "Zero Page" addressing nature of this mode, no carry is added
to the high order 8 bits of memory and crossing of page boundaries does not occur
INDEXED ABSOLUTE ADDRESSING — (X, Y indexing) — This form of addressing is used in conjunction with X and Y index
registet and is referred to as “Absolute, X', and “Absolute, Y". The effective address is formed by adding the contents of X
or Y to the address contained in the second and third bytes of the instruction. This mode allows the index register to
contain the index or count value and the instruction to contain the base address. This type of indexing allows any location
referencing and the index to modify multiple fields resulting in reduced coding and execution time.
IMPLIED ADDRESSING — in the implied addressing mode, the address containing the operand is implicitly stated in the
operation code of the instruction.
RELATIVE ADDRESSING — Relative addressing is used only with branch instructions and establishes a destination
for the conditional branch
The second byte of the instruction becomes the operand which is an “offset" added to the contents of the lower eight bits
of the program counter when the counter is set at the next instruction. The range of the offset is - 128to + 127 bytes from
the next instruction
INDEXED INDIRECT ADDRESSING — in indexed indirect addressing (referred to as (Indirect,X)), the second byte of the
instruction is added to the contents of the X index register, discarding the carry. The result of this addition points to a
memory location on page zero whose contents is the low order eight bits of the effective address. Both memory locations
specifying the high and low order bytes of the effective address must be in page zero.
INDIRECT INDEXED ADDRESSING — In indirect indexed addressing (referred to as (Indirect),Y), the second byte of the
instruction points to a memory location in page zero. The contents of this memory location is added to the contents of the
Y index register, the result being the low order eight bits of the effective address. The carry from this addition is added to
the contents of the next page zero memory location, the result being the high order eight bits of the effective address.
ABSOLUTE INDIRECT — The second byte of the instruction contains the low order eight bits of a memory location. The
high order eight bits of that memory location is contained in the third byte of the instruction. The contents of the fully
specified memory location is the low order byte of the effective address. The next memory location contains the high order
byte of the effective address which 1s loaded into the sixteen bits of the program counter
Figure 13.4 Addressing modes of the 6502 eight-bit microprocessor. Note the
complex addressing modes using both indexing and indirection. These permit
very efficient data handling structures and are one of the reasons for the wide
use of this MPU in personal computers
Machine code 103
endowed with indexed addressing modes and they are detailed in
Fig.13.4. though the ability to make effective use of all these address-
ing modes only comes with experience.
The Oric does not have a built-in machine code monitor, but you
can enter the code with POKES, either in immediate mode or from
program, as in some of the following examples. (Note that early
versions of Oric BASIC will not accept hex values after the comma in
POKE statements: convert them to decimal first.) Once entered, the
machine code can be saved using CSAVE’/NN’”’, AXXXX,EYYYY. NN
is the name you give the routine, if any. The start Address of the code,
XXXX, and its End address, YYYY, may be in either hex or decimal.
A machine code application
You may be thinking that dabbling in machine code looks a bit
complicated and fiddly, so is it worth it? Well, here’s a practical
demonstration. It can be very useful in a number of applications
(including games) to be able to store the present screen display and
10 REM ### BASIC SCREEN SWAP ###
20 REM STORES CURRENT TEXT OR LORES
30 REM SCREEN DISPLAY IN SPARE RAM
40 REM AND REPLACES IT WITH DISPLAY
SO REM PREVIOUSLY STORED IN SPARE
100 REM SC=SCREEN, SP=SPARE, OS=OFFSET
110 OS=-4096
120 FORSC=#BR80TO#BFEO
130 X=PEEK (SC)
140 SP=SC+0S
150 Y=PEEK (SP)
160 POKESP, X:POKESC,Y
170 NEXT
Figure 13.5 BASIC ‘Screen Swap’ program
replace it with another. Figure 13.5 is a short BASIC routine to do just
this. For each and every screen location (line 120) it reads what is held
in that location (line 130), calculates the address of the SPare RAM
where it is going to store it (line 140) and reads what is already held in
SPare (line 150). It then swaps the SCreen and SPare characters (line
160) and moves on to the next location, (line 170).
If you run the program, you will find it takes several seconds to
swap the whole screen, far too slow to be useful. (The first time you
run it after switching on you are likely to find the screen fill up with Us.
The ASCII code for U is 85, or 01010101 in binary. This pattern of Os
104 Machine code
and 1s is used to exercise the whole of RAM memory during Oric’s
switch-on initialisation routine, leading to the 47870 BYTES FREE
message. The pattern of alternate Os and 1s is a good test of the
correct operation of each byte of memory.) Running the program
again will store the new screen information and restore the original.
But watch where the cursor is: if you call the subroutine with the
cursor on the bottom line, the subsequent READY message will scroll
the top line of the swapped screen straight off the top of the screen!
‘BASIC SCREEN SWAP’ could be incorporated as a subroutine in a
longer program and called as required with a GOSUB, but it really is
too slow to be useful. What we need is a machine code ‘SCREEN
10 REM “SCREEN SWAF" ROUTINE FOR ORIC I
12 REM LOAD & RUN BEFORE LOADING A PROGRAM,
14 REM OR INCORPORATE IN THE PROGRAM
16 REM CALL#9000 TO SWAF SCREEN, DITTO TO SWAF BACK AGAIN
18 FORX=#9000TO#9054
20 READY: POKEX, Y
30 NEXT
40 DATA#AO, #00, #RE, #80, HBR, HBO, #00, HBO, #99, #80, HEE
41 DATA#BA, #99, #00, HBO, #08, #DO, HFO
42 DATA#BE, #80, HBC, #B9, #00, #B1, #99, #80
43 DATA#EC, #8A, #99, #00, #B1, #C8, #DO, #FO
44 DATA#BE, #80, #BD, #B9, #00, HERZ, #99, HBO
45 DATA#BD, #8A, #99, #00, #B2, #C8, #DO, HFO
46 DATA#BE, #80, #BE, #E9, #00, HBS, #99, #80
47 DATA#BE, #8A, #99, #00, #B3, #06, #DO, HFO
48 DATAHAO, #60, #BE, #80, HEF, #B9, #00, #B4
49 DATAHID, #80, HBF, #8A, #99, #00, #B4, #88
SO DATA#IO, HFO, #60
SS PRINT
60 FORX=1T085: S=FEEK (#8FFF+X)"
70 PRINTHEX$ (S) ¢sNEXT
80 END
Figure 13.6 BASIC loader for machine code ‘Screen Swap’. It may be relocated
to #400 by changing #9000 and #9054 on lines 16 and 18 to #400 and #454
SWAP’, and Fig.13.6 is a BASIC program that will load such a
machine code routine into memory, starting at memory address
#9000 or 36864d. It would therefore be wise to restrict BASIC to less
than this by entering HIMEM#8FFF. Then run the program, which
will load the machine code routine. Just to let you know that it has
done so, the program finishes by printing out the 85 bytes it has just
loaded at #9000 onwards.
The code was produced with the aid of a 6502 assembler for the
Oric; see Appendix 7. This modestly priced cassette has the
assembler at the usual fast speed, followed by the same again
recorded at the 300 baud slow speed on one side, and a disassembler
similarly recorded on the other sid@. A disassembler works the other
way round from an assembler, i.e. it turns object code back into
source code (mnemonics). | found it more reliable to load the
Machine code 105
assembler at the slow speed. To save time on later occasions, | re-
recorded it at 4800 baud on a chrome dioxide cassette, and it now
loads completely reliably at the fast rate.
100 EQU#BR80=SCR
110 EQU#B000=SFA
120 AO OO LDY #00
130 BE 80 BO LOOP LDX;Y SCR
140 B9 OO BO LDA;Y SPA
150 99 80 BR STA:Y SCR
160 BA TXA
170 99 00 BO STA:Y SPA
180 C8 INY
190 DO FO BNE LOOP
Figure 13.7 Writing part of the routine in Fig. 13.6 with the aid of an assembler
Figure 13.7 shows the first part of the assembly process. On the left
are arbitrary line numbers. There are no memory address locations
shown; these are worked out by the assembler during assembly,
given the start address. The next item on the line is the assembled
machine code, often called ‘object code’. Next follows the label
column and then the mnemonic code, also called ‘source code’.
The first two lines define the start of SCReen memory and the start
of SPAre memory, in high, low byte order. Line 120 LoaDs the Y
index register of the 6502 (see Figure 13.3) with the value zero (op-
code #A0 followed by #00) and line 130 LoaDs the X index register
(which we will use as a temporary store) with the screen byte stored at
SCR, ine. at #BB80. The op-code for LDX indexed by Y is BE and the
address 00 BO follows in low, high byte order. ‘Indexed by Y’ means
that the register is loaded from address (SCR + contents of Y register).
Line 140 loads the accumulator from SPA indexed by Y and line 150
stores the SPA byte back in SCR indexed by Y. Line 160 transfers the
byte stored in X to the accumulator and line 170 stores it in SPA
indexed by Y. (There is actually an op-code which would let us store
the contents of X in SPA directly.)
So now we have swapped the top left character on the screen with
the corresponding one in the SPAre screen. Line 180 increments Y by
1 and line 190 tests to see if Y = 0. If it doesn’t, the program branches
back to line 130, i.e. the line tagged with the LOOP label. The op-
code for BNE is DO and if the test succeeds (i.e. Y <> 0) the program
will ‘Branch on tested register Not Equal to zero’. The tested register is
always the one involved in the last operation, in this case the Y index
register. A branch is a relative jump of not more than 128 bytes or so.
In this case the branch is calculated by the assembler, at assembly
time, as #FO in two’s complement notation, i.e. —15. Program
106 Machine code
execution therefore continues after the content of the program
counter has been decremented by 15 (i.e. it has branched back to
line 130) but with Y now set to 1.
So now the contents of SCR+1 (BB81) and SPA+1 (BO01) are
swapped and so on. Aiter swapping SCR+255 and SPA+255,
almost a quarter of the screen has been swapped, but this time, when
Y is incremented to 255+1, in effect Y is set back to zero (the eight-bit
Y register has no carry). Thus the BNE test fails and the program
continues to the next section — not shown in Fig. 13.7 — where SCR
and SPA are redefined as #BC80 and #B100 respectively, i.e. 256
addresses further on. Thus the next quarter of the screen is swapped,
and so on. After swapping 1024 addresses there are the odd 96 still to
go — see if you can work out how the last 21 bytes of the subroutine
in Fig.13.6 achieve this. The subroutine ends with op-code #60, i.e.
RTS, return from subroutine.
The labels SCR, SPA and LOOP are used by the assembler, but
only at assembly time. They define absolute addresses (anywhere in
the full 64K address range) and relative (branch) addresses and they
get turned into the corresponding hex addreses in the object code, at
assembly time. Once this is done, the source code and indeed the
assembler itself are no longer required; the object code can be run
when ever required, or CSAVEd for use another time — no need to
use the assembler to load again.
You will notice a difference when you run this program in place of
‘BASIC SCREEN SWAP’! CALL 9000 will swap the screen instantly, in
less than a thousandth of a second — thousands of times faster than
the BASIC version, and much less time than it takes the TV set to
display one complete ‘field’ or picture.
It can be seen that the simple assembler program mentioned above
is exceedingly useful, despite two limitations. It does not support a
COMMENT field and it cannot cope with forward branches. (In line
190 of Fig. 13.7, on encountering the label LOOP, the assembler was
able.to calculate the negative displacement #FO because it had
already met the label LOOP and noted the corresponding address, in
line 130. However, if the destination LOOP were in a line after line
190, this assembler would not be able to handle it. The user would
have to calculate manually any forward branches and insert the
actual number of bytes displacement. A full assembler, however, can
cope with forward branches.)
Entering odd bits of machine code is much easier with the aid of a
machine code monitor, since once you have set up the start address
of the code, you can simply enter it byte after byte in hex without
needing to precede each byte with a hash. The monitor will automati-
cally enter the-first byte at the start address and succeeding bytes at
consecutive addresses thereafter.
Machine code 107
Life is even easier with an assembler, as we have seen. A complete
machine code monitor including mnemonic assembler/disassembler
with ‘block move’ and ‘verify’ is available for the Oric (see Appendix
7). It sounds very well worth having, even though a bit more expen-
sive than the simple assembler/disassembler mentioned earlier. The
real beauty of an assembler becomes apparent when we have just
used it to produce object code for a long subroutine or program with
lots of relative branches — and we then realise that we have left out an
essential couple of lines. If we were hand coding we would need,
after inserting the missing lines, to go through and readjust all the
relative instructions — BNE, BCS, BEQ, BIT, etc. The assembler will
do all of that for us at the touch of a button, provided we have used
labels rather than constants for branch displacements; we simply
instruct it to produce a new object code listing.
So an assembler vastly increases the speed and accuracy with
which machine code programs can be written; writing more than a
few tens of lines in hand coding becomes very time-consuming and
tedious. With an assembler, machine code programming is not vastly
more difficult than using BASIC, though one would lift ready-made
machine code subroutines for, say, arithmetic operations from one of
the ‘cookbooks’ of machine code programs for the 6502.
If however you want to try your hand at machine code program-
ming but have no assembler (and that is the way most of us start) there
is a dodge that eases the problem of relative branch addresses.
Simply include four or five NOPs between each line of the program
proper. A NOP, NO OPERATION (EA in 6502 code), is a machine
code instruction which does nothing and serves no (directly) useful
purpose, but it does occupy a program memory location. Thus if you
later need to insert an instruction or two, the dummy addresses previ-
ously occupied by NOPs can be used and thus you may avoid the
need to comb through and readjust the relative branches. Of course
the NOPs will slow down the program execution, but not nearly as
much as you might fear. On the 6502, a NOP executes in only two
machine code cycles as against three to seven for other instructions.
So your machine code program will still run about one hundred times
faster than BASIC. Don’t forget that with five NOPs between active
lines of code, by shunting an instruction, which is neither a branch
instruction itself nor the address to which a branch points, back or
forward next to another instruction, you can accumulate a block of
ten or more free addresses for inserting extra code.
This completes our brief look at machine code program examples,
but there are one or two other topics which must at least be
mentioned. These topics are the stack, interrupts and breaks, and
masking; they are to some extent interrelated. Let's first look at the
concept of a stack.
108 Machine code
The stack, interrupts and breaks
Imagine a newspaper sub-editor working on the front page story for
tomorrow’s edition. In comes a cub reporter with a scoop, so the
sub-editor puts his story in the pending tray and starts work on the
scoop. Now in runs another reporter with an even bigger story,.and
the cub’s scoop goes into the pending tray on top of the story already
waiting there. When the sub-editor has finished preparing the big
story he will go back to the cub’s scoop and finally to the story on
which he was originally working. Thus his pending tray is a ‘last in,
first out’ memory, or LIFO.
The stack in a microcomputer system works in the same way, as a
LIFO ‘holding memory’ for data that will be wanted again shortly. A
single-chip process-control microcomputer might contain its own set
or stack of registers, while a large computer might have a special
block of memory dedicated to operation as a stack — both ‘hardware
stacks’. Most home computers just use a part of the main RAM area
for this purpose, and thus use a ‘software stack’. For example the
6502 microprocessor locates its stack in page one of memory
(memory locations #0100 to #01FF) by automatically supplying
#01 (0000 0001 in binary) on the eight most significant lines of the
address bus whenever writing to (‘pushing’ data onto) or reading
from (‘pulling’ or ‘popping’ data from) the stack. The eight least
significant bits of the current stack address are held in a register in the
microprocessor known as the ‘stack pointer’ (see Figs 13.3 and 13.8).
Each time a byte is pushed onto the stack, the stack pointer is
automatically adjusted, and likewise it is readjusted when a
byte is pulled from the stack. This clearly results in the ‘last in, first out’
operation described above. A typical example of the use of the stack
is when the microprocessor encounters a jump to subroutine (JSR)
command in the program it is executing.
As explained earlier in the chapter, the MPU keeps track of where
it is in the program that it is executing by holding in its 16-bit Program
Counter register the address which it is currently reading: it will
expect to find at that address either an instruction (an op-code), or an
address, or data, depending on a previous instruction. Normally, as
the MPU works its way through the program, the Program Counter
will be updated sequentially. When however the MPU encounters a
JSR comman4d, it will read the following two memory locations which
give the address of the start of the subroutine, and will load these into
the Program Counter. Thus program execution will continue with the
subroutine, which could be located almost anywhere in the full 64K
memory range — for example with a subroutine in the BASIC ROM,
or in an EPROM (erasable programmable read only memory) in
which we have stored a frequently required subroutine so that we do
Machine code 109
not need to include it in every program that may need to use it.
But having executed the subroutine, how does the MPU get back
to where it should be in the program? The answer is that, before
jumping to the subroutine, the MPU automatically executed a little
sub-subroutine or ‘microprogram’ stored in the MPU’s control section
(see Fig.13.8). As a result of the instruction-decode and control
section of the MPU recognising the JSR instruction, the MPU auto-
matically stores the high and low bytes of the current address — held
in the Program Counter — on the stack. This results in the Stack
Pointer register in the MPU being incremented by two. (Actually, in
the 6502 the stack builds backwards, towards the start of page one,
so the Stack Pointer actually gets decremented. The Stack Pointer
always points at the next free stack location to be occupied.)
At the end of the subroutine, the programmer will have placed an
RTS (return from subroutine) instruction, and on encountering this,
the instruction-decode and control section of the MPU will cause two
bytes to be pulled from the stack (adjusting the Stack Pointer accord-
ingly) and loaded into the Program Counter. Now you will recall that
following the JSR instruction, the MPU had to read the next two bytes
to find the address of the start of the subroutine. The return address
stored on the stack then was actually the memory address of the
instruction following the two bytes of the subroutine address. Thus on
returning, the program simply picks up at this address, i.e. at the next
instruction.
Of course, before returning, the subroutine may itself call a second
subroutine, and the second a third, and so on. But as each will end
with an RTS the LIFO structure of the stack will eventually return us to
the instruction following the original subroutine call. (In contrast, the
instruction JMP followed by a two-byte address XXXX, will cause a
one-way jump to the section of program stored at location XXXX
onwards, without storing any return address on the stack.)
It might be thought that a machine code program is entirely cut and
dried, its operation completely determinate, down to the last
microsecond of execution time. In the absence of any outside influ-
ences this is indeed true, but it is sometimes necessary to arrange fora
microprocessor-based system to react to external influences as and
when required. Thus if you had your Oric rigged up to control the
heating, lighting and watering of a greenhouse, it would need to
respond to the temperature, a light meter and a humidity sensor as
required and send control signals to adjust the switches and valves
controlling heaters, blinds or lights and sprinklers. It would be simple
to program the computer to scan the three sensors in turn continu-
ously (a polling arrangement), but that would tie up the computer and
prevent you using it for Space Invaders. So an alternative scheme
would be to arrange the computer to service the sensors on an
‘interrupt’ basis.
110 Machine code
+ resister sectin ————+}e
Index
register
Y
a
Vv
Marr ——)
¥
a Te
aes
NN]
=
<
=
=
=
v
3
4
al
y
o
=
ae]
so]
<
Internal ADL
wn
: =o
mts
Sto
‘ g°.
3
=>
Internataatabus] | i. dd
logic unit
(ALU)
Address bus
counter
(low)
Program
(—___ __— }_ counter
(high)
Internal ADH
Address bus (low)
Legend
1 = 8 bit line
] = 1 bit line
Figure 13.8 Inside the heart of Oric, the 6502 MPU
Machine code 111
tit sction
ane ina Nui Vector Addresses
al. alle High part
NMI FFFA
Interrupt
logic
7
SYNC
es RDY
50
P—register
Carry 1 = True
Zero 1 = Result zero
IRQ disable 1 = Disable
Decimal mode 1 = True
BRK command 1=BRK
Overflow 1 = True
Negative 1 = Neg
Instruction
decode
le) = Timing
if control
—
ante L Ghack input (00 in)
register
=e 9 Out
2 Out
R/W
ee]
ee]
Het 33
DO
Dl
D2
D3 \ Data
D4 (bus
D5
D6
112 Machine code
Here, each sensor would simply signal to the computer that it was
too hot or cold, too light or dark, etc. via an Input/Output (I/O) inter-
face unit, whereupon the computer would adjust the heating or
whatever and then return to the Space Invaders. On receiving an
interrupt, the MPU would service it by jumping to a section of
machine code program which effects the required adjustment, and
then return to the program it was engaged in prior to the interrupt.
Thus an interrupt can be considered as a hardware initiated sub-
routine call — but there is a difference. It can arrive at any time, e.g.
when the MPU is in the middle of a calculation, and most likely when
it is part way through reading an instruction. The current instruction
will be completed by the MPU before servicing the interrupt, and as
with a JSR, the return address will be stored on the stack.
The 6502, on receiving an interrupt, also stores flags — the
contents of the Status register — on the stack, and restores them after
returning from the interrupt. The interrupt causes the 6502 to jump to
a memory location whose address is stored in #FFFE, #FFFF; let’s
call this memory location XXXX. XXXX would be the location of the
start of the subroutine (which must be supplied by the programmer
and entered into memory at switch-on, or stored in ROM) and might
commence by polling several inputs (our three greenhouse sensors,
for example) to find which caused the interrupt. As a result of this test
the MPU could go to the appropriate control subroutine. However,
we could easily be in trouble on returning to the main program after
servicing the interrupt. The Program Counter will be set to the address
of the next instruction in the main program and the contents of the
Status register will be restored for us, but we will almost certainly have
lost irretrievably the contents of the Accumulator and Index registers.
Thus on a 6502-based machine one should arrange that the first task
on entering an interrupt routine is to save on the stack any registers
(other than the Program Counter and Status register, which are saved
automatically) which may be required later.
We have seen how a hardware interrupt — caused by a device
external to the computer demanding service — is handled, but an
interrupt can also be built into a program. This is called a software
interrupt or ‘break’. The break is an instruction and it must therefore
be inserted in the code at a point at which the MPU expects to find an
instruction. Thus if a section of code were, for example:
LDA $#FF STA #XXXX
(load 255 dec. into the accumulator and store it at location XXXX hex)
which would appear in 6502 machine code as
A9FF8DXXXX
Machine code 113
then the break instruction (for which the 6502 op code is 00) could be
inserted in place of the A9 or 8D (LDA or STA). Clearly, inserting the
break instruction 00 in place of FF would not do, as the MPU would
simply load the accumulator with zero instead of FF and carry straight
on with the program. If the program proves to be correct up to this
point, the break is then eliminated by reinstating the instruction A9
which was earlier replaced by the break.
A typical use for the break command is in debugging a machine
code program. If it is found that a newly written program does not run
correctly (a not unusual occurrence!) the insertion of breaks at
intervals can greatly assist the diagnosis of the trouble. The program is
run again and on encountering a break instruction the machine
behaves as though interrupted, i.e. it jumps to the appropriate sub-
routine. This will be, for example, an existing subroutine in the
monitor/assembler/disassembler mentioned earlier, which enables
the operator to examine the contents of the Flags or Status register,
other MPU registers and memory locations, to determine that all is as
expected. Indeed, the mere fact that the program safely reached the
break indicates that it is most likely OK up to that point. That
particular break point can then be eliminated and the program rerun
to see if it reaches the next break point. If this time it crashes (indicated
by failure to enter the ‘inspect/modify registers’ mode of the monitor
normally called up by the break command) then the fault in the code
lies between the break point just eliminated and the following break
point, which it failed to reach. In this way, the code can be corrected
up to each successive break point and that break then eliminated,
until the whole program is bug-free.
It is suggested that if you are hand coding, without the assistance of
an assembler or even a disassembler (the latter takes lines of object
code and turns them back into source — i.e. mnemonic — code, and
incidentally flags up such errors in the coding as it can recognise) then
a few NOP (no operation) instructions should be included in your
code. Some of these NOPs can then conveniently be changed to
breaks when debugging, thus avoiding the need to change the actual
working lines of code at all.
Finally, let’s look at the concept of masking. This is often used, for
example, to modify the contents of a register so that only one
particular bit (e.g. the MSB) retains its original value, all the other bits
being set to zero. We have looked in Chapter 7 at the AND function
of two variables, among other things. MPUs enable us to perform the
AND function between two bytes, i.e. between two eight-bit
numbers. This is defined as meaning that each bit of the result is found
by ANDing the corresponding bits of the two original bytes. Thus if
we AND #80 and #B5 the result is #80 as can be seen by looking at
the numbers in binary notation rather than in hex:
114 Machine code
1000 0000 (#80)
AND 10110101 (#B5)
=1000 0000
since it is only bit seven which is a 1 in both bytes. Had we ANDed
#80 and #35 (#35 is the same as #B5 except that bit seven is zero
instead of 1) the result would have been #00. Thus the ‘mask’ #80,
when ANDed with the eight-bit contents of any register or memory
location will always give a result of #80 or #00 depending on
whether bit seven of the register is 1 or zero, regardless of the value of
the other bits in the register.
Now bit seven is often used as the ‘status bit’ of a device which has
to interface with a microprocessor system, e.g. the sensors in our
greenhouse example. Thus in polling the three sensors following an
interrupt to determine which required service, the subroutine would
load the contents of the status register of each sensor input in turn,
AND with #80 and then check whether the result was non-zero — in
which case that input requires servicing.
We can also OR or EXOR the contents of a register, e.g. the
accumulator, with any number in the range zero to 255 decimal.
Thus for example, EXCLUSIVE ORing a byte with #FF will provide
the complement of that byte; that is, each bit which was a 1 in the
original will be a 0 in the result and vice versa. Adding 1 to the result
will then give the two’s complement, a useful result described in
Chapter 7.
But let’s stick with ANDing for the moment and look at another
typical use for a mask. This consists quite simply of ANDing a register
with #FO or #0F in order to select the MSN (most significant nibble)
or LSN of a byte. This is clearly useful in the BCD (binary coded
decimal) mode of operation, as it provides immediate access to the
contents of the ones or tens column of a result.
Masking and ‘bit testing’ (checking bits of the MPU Status register,
such as the zero bit, carry bit or sign bit) are both important and
widely used operations in machine code programming.
In this chapter we have only been able to skim the surface of 6502
machine code programming. If you want to delve further into the
subject it is best to get hold of one of the various books devoted to the
topic. One of the most comprehensive is Programming the 6502 by
Rodney Zaks, published by Sybex Inc.
How a BASIC program is stored
To close this chapter, let’s look at how a BASIC program is stored —
in machine code, naturally. ORIC stores any program you enter,
Machine code 115
either from keyboard or cassette, in RAM at address #500 (1280d)
onwards. We can write a program to look at itself, like the Eastern
philosopher contemplating his navel. It is instructive to do so (to look
at the program, that is), so try entering the short program of
Fig.13.9(a).
X=1280
Z=PEEK (xX)
PRINTX3Z3 2 X=X+1
GOTO20
FORX=0TO255: IFDEEK (X) =1409THEN7O
60 NEXT
70 PRINTX;DEEK (X) sEND
80 FORM=1280T01780: POKE#8000+M, PEEK (M) : NEXT
1280 © 1281 12 1282 5 1283 10 1284 © 1285 88 1286 212 1287 49
1288 5O 1289 56 1290 48 1291 O 1292 23 1293 5 1294 20 1295 0 1296
(c) 9125 10 © 88 212 49 50 56 48 © 23 S 20 6 9O 212 230 40 88 41 0
39 5 30 6 186 88 59 90 59 58 88 212 88 204 49 0 52 5 40 0 153 88
213 50 48 151 50 48
Figure 13.9 BASIC ‘Explorer’
When run, this will print out numbers almost for ever more, so be
ready with a CONTROL C to stop it! The printout on the screen
consists of addresses and their contents as in Fig. 13.9(b). Leaving out
the addresses just prints the contents, as shown in Fig.13.9(c).
Ignoring the initial 0, the next 11 numbers actually constitute the first
line of the program. 10 O is the line number. This is stored as a two-bit
binary number in low, high byte order, but BASIC has printed it out
for us as decimal equivalents of each byte. Thus line number 200
would appear as 200 0 but line 300 would appear as 44 1, i.e. 1 X
256 + 44. The next figure, 88, is X in ASCII. After that we have 212,
which, being greater than 127, is not an ASCII code. It is in fact a
‘token’ which BASIC understands as meaning ‘equals’. Constants are
stored as ASCII strings, hence 1280 appears as 49 50 56 48. 0 is the
end of line marker.
At the start of the line is the ‘link address’, again in low, high byte
order. Here, itis 12 5; 5 X 256 + 12 = 1292. It thus indicates the
location of the first byte of the next line, hence the name link address.
By using tokens for BASIC commands, the whole line, complete with
its link address, line number and line terminator, is packed into only
11 bytes. By adding other lines with different commands and looking
at the screen when RUN, you can find out all the different tokens and
what they mean.
Address 1406 holds the zero which terminates line 80 — provided
116 Machine code
you have entered the program with nospacesatall. The next two
addresses hold zeros as well. This null link address tells BASIC that-
there are no more lines of program. Thus 1409, 1410 is the next free
line-number location.
You can also use the program to explore page 0, the ‘scratch pad’
area extensively used by BASIC for storing and updating addresses,
pointers, vectors and any other information to which it needs quick
access. If you RUN 50, the program will show that the address of the
first byte of the next free line number (1409 in this instance) is stored in
page 0 at location 97. If you then GOTO 60, you will find that it is also
stored at 156. (This only applies if you have entered the program
exactly as printed and not added or deleted lines, since first switching
on.) If you add ten spaces at the end of line 60, you will find that 156/7
now holds 1419. RUN will show ten spaces (ASCII code 32) follow-
ing the token 144 (NEXT) in line 60. (Thus in Oric BASIC, spaces in
programs can eat up quite a lot of memory, unlike some other
BASICs. In these, a string of spaces is indicated by a special token
followed by the number of spaces.)
We have seen that location 156 is updated whenever a change is
made to the program, but it turns out that location 97 isn’t. RUN 80
will reduplicate the contents of 500 locations starting at 1280, into the
500 addresses starting at #8000, i.e. 32768d. For alongish program,
500 bytes might not be enough. You can tack the little routine of
1000 Z=1281
1010 A=Z
1020 Z=DEEK (Z)
1030 IFZ=OTHENFRINTA: END
1940 GOTO1010
Figure 13.10 ‘Find end of BASIC’ routine
Fig. 13.10 onto the end of a program: RUN 1000 will zip through the
linked line numbers and print out the address of the end of your
BASIC program; call it E, say. Then
FOR X = 1280 TO E:POKE#7B00+ X, PEEK(X): NEXT
will reduplicate the program starting at #8000. Of course the
program won’t RUN from 32768, as the link addresses are all wrong.
However, maybe by loading #8001 as the link address at the end of a
new program entered after reduplicating as above and readjusting
the page 0 pointers, it will prove possible to link the two programs
together. Entering a dummy new line, e.g. 1 PRINT, and then
deleting it, should cause the BASIC linking routine to relink every-
thing. At least that’s the theory — I’m still working on it!
Printers and hard copy
The manual’s chapter on using printers seems to have been written
before the Oric printer became available. Many readers will, like me,
possess other printers and the first part of this chapter deals with using
Oric with another printer. In fact many of the program examples in
this book are printed on an Epson MX80FT. This is just about as stan-
dard a dot matrix printer as you will ever find, although now actually
replaced by a later model with more extensive graphics facilities. The
second section of the chapter deals with the Oric printer proper.
Using Oric with an Epson MX80FT printer
The first hurdle was connecting the printer to the Oric — my earlier
computer talks to the printer over a serial RS232 link at 4800 baud.
After rearranging the printer to work on the Centronics interface by
removing the RS232 adaptor (as the printer’s handbook instructs), |
obtained a Centronics printer lead similar to that used on the Dragon
and Apple computers. This fitted perfectly at each end, so | looked
forward to bursting into print — which brought us to the second
hurdle. Having checked that there was paper in the printer (it has an
OUT OF PAPER sensor which prevents one printing without paper)
and that the printer ON LINE indicator light was on, | entered the
manual’s PRINTER TEST program, typed RUN and expectantly
pressed RETURN. The resulting printout was
18
19
146
147
118 Printers and hard copy
the 147 not appearing until | put the printer OFF LINE with another
touch of the ON LINE button.
LLIST was even more disappointing, doing absolutely nothing.
Obviously | was not talking a language the printer wanted to hear so,
following the Oric manual’s advice, | turned to the printer handbook.
This told me that 17 is a control code which places the printer in the
‘selected’ state, in which data is receivable. So when the program
was RUN, following CHR$(17), 18 and 19 would be printed just as
described earlier. However, CHR$(19) is the control code placing
the printer in the ‘deselected’ state again, so the ASCII characters
corresponding to 32 to 127, i.e. the printable characters as distinct
form control codes 0-31 (see Appendix 3) just never got printed. The
control codes corresponding to 0-31 appear again at 128-159,
hence the observed printout of 146 and 147.
| now knew enough to start printing out the program illustrations in
this chapter and throughout the book. But just occasionally an odd
character at random would be missing from the printout: most
mystifying and disturbing. The solution to this problem turned up just
in the nick of time in Issue 2 of the Oric Owner. Owing to a lapse in
the software the printer port randomly outputs character 7F hex. This
is due to the keyboard scanning interrupts interacting with the
printer port.
Now as Appendix 3 shows, CHR$(127) is the DELETE code, which
deletes the preceding character from the printer’s input buffer. The
recommended fix for this is to turn off the keyboard interrupts with
CALL #E6CA before printing and turn them on again afterwards with
CALL #E804. This works, but some care is needed, as once you turn
off the keyboard interrupts you no longer have control of the
machine! If a routine using CALL #E6CA fails and the eomputer
crashes, just press RESET and usually all will be well.
Figure 14.1(a) is a printer test program that runs well with an Epson
MX80FT and should run with almost any other Centronics interfaced
printer. The CALL to #E6CA really does work, as you can prove by
omitting the CALL #E804 in line 80 — you will then need to RESET to
regain control. Figure 14.1(b) shows the resultant printout and you
can check that the block graphics are the same as those of Oric
(though the aspect ratio of the blocks is a bit different) by running the
program in Fig. 14.2.
RUNnhing the Figure 14.1(a) program will print out the character set
and graphics as in Fig. 14.1(b), but how was the program itself
printed out? The full program is shown in Fig. 14.1(c) and is printed
out by typing RUN330. The listing in Fig. 14.1(a) was produced the
same way but with ‘10—330’ in line 330 changed to ‘10—210’: so you
see that the LLIST command works exactly like LIST, except that it
routes data to the printer instead of the screen. Similarly, LPRINT
Printers and hard copy 119
REM ##PRINTER TEST##
REM FOR EPSON MX80FT & SIMILAR
LPRINTCHR$ (17)
CALL#E4CA
$=32+T
GOSUB170
S=S+48
GOSUB170
IFA=1THENCALL#E804: END
A=1:T=128
GOTO49
FORN=ST0OS+47
LPRINTCHRS(N) 5
NEXT
LPRINTCHRS (13)
RETURN
SHBL~R? () K+, —. /01 23456789: 5 <=>? D9ABCDEFGHIJEKLMNO
POQRSTUVWXYZEO\I"_“‘abcdefghi jkilmnopqrstuvwx yz C13”
; = i = pare OO halal weet Ot el
REM ##PRINTER TEST##
REM FOR EPSON MX8OFT & SIMILAR
LPRINTCHR$ (17)
CALL#E6CA
=S32+T
GOSE170
S=S+48
GOSUB170
IFA=1 THENCALL#E804: END
A=1:T=128
GOTO49
FORN=STOS+47
LPRINTCHRS(N) 5
NEXT
LFRINTCHRS (12)
RETURN
LFRINTCHRS$ (17) sLLIST1IO-—330: CALL#E6CA
Figure 14.1 Printer test for dot matrix printers
120 Printers and hard copy
LORES1
N=32
FORY=0TO1: FORX=2T034
AS=CHR$ (N)
PLOTX,Y,A%
N=N+1
NEXT: NEXT
Figure 14.2 Oric LORES1 graphics display
(a)
10 LPRINTCHR$ (17)
15 CALL#E6CA
20 FORN=32T0127
ZO LPRINTN;CHRS(N) 3"
40 NEXT N
SO LPRINT
60 FORN=160T0255
70 LPRINTN;CHRS(N) 3"
80 NEXT N
90 LFRINTCHR$ (13)
100 CALL#E804
(b)
32 1 34 35 36 $ 40
43 45 46 47 / 51
54 56 57 58: c 62 >
65 67 68 69 E 76 73 1
76 78 79 80 P 84 T
87 a9 90 91 95 _
98 100 d 101 e 102 o7 OF h 105 i 106 5
1081 109m 110n 1110 3 114r 115s 116¢t
117 u 118 Vv 119 w 120 » 2 123 € 1241 125
126 ~ 127
160. 161" 162 166 167 F
169% 170 8 171 175 176
178" 179 = 180 2 : 184 tes 186
187 § 188 189 : 193 194 195
196 197 198 200 0 202 203 4 204
CTErpoert
168
177
205 206 207 O 20) 2 211 212 213
214 215 216 2 2 220 221 222
223 224 225 22) eZ e 230 231
232 233 234 235 2 3 239 240
241 242 243 244 2 2 2 248 249
250 251 252 253
Figure 14.3 Revised Oric ‘PRINTER TEST’ program and its output
Printers and hard copy 121
works just like PRINT. The program only sends the 96 printable ASCII
characters to the printer — 32 to 127 — and it does so in two chunks
of 48 to a line (lines 40 and 60). It then adds 128 to S and so sends
characters 160 to 255, although only 64 of these graphics characters
are printable.
I'm not sure whether the CALL #E6CA in line 330 has any effect or
not. Certainly, after the LLISTing, control is returned to the keyboard,
so either the CALL #E6CA is ignored or BASIC automatically restores
interrupts after an LLIST. If you suspect that the odd #7F is getting
through and spoiling your printout, you will find it very tedious to go
through a page of printing looking for any missing character. So the
dodge is to print it out again — it is most unlikely that the same
character will be missing in both. Now place one sheet on top of the
other and hold them up to a strong light. Once the two lots of printing
are lined up, any differences will stand out immediately since,
following a missing character, the rest of the line will be displaced to
the left.
If you wish to see which code corresponds to which graphics
character, Fig.14.3(a) is a revised version of the Oric Manual’s
PRINTER TEST. The printout it produces is shown in Fig.14.3(b)
where, for clarity, each character is preceded by one space and
followed by two more. CHR$(127) is the DELETE code, so it is a non-
printing code. In this case, it deleted the previous character, which
was a space anyway!
The Oric printer
The first test | performed with the Oric printer was to try out the printer
demonstration program in the Oric manual. | can confirm that it does
work, more or less as intended. Of course, the first 32 numbers are
non-printing control codes and printout may not start until CHR$(17)
has been sent. From N = 32 onwards, the output will appear in the
format of Fig. 14.4 which shows a short section of the printout. For
values of N from 128 to 255 we get a straight re-run of the printout up
to 127, so left to run its course the program will consume a fair length
of paper! The odd squiggle, due to spurious #7F outputs from the
computer’s printer port, is evident, so that a CALL #E6CA is needed,
as described earlier in the chapter. So | decided, as an exercise, to
write a tidied-up version of the program and this appears as Fig. 14.5.
When ‘ORIC-1 PRINTER CHARACTER SET’ is run, line 50 calls the
subroutine which turns off the keyboard-scanning interrupts, to
avoid the problem mentioned earlier. In line 60, LPRINTCHR$(18)
sets the printer to the graphics mode, which sounds an odd thing to
do. But in graphics mode we can call up a specific pen colour (in this
122 Printers and hard copy
>uU7yTAWwWxKXKECCANADO
a
b
c
d
e
f
9
h
Rl
12
13
14
15
116
11?
118
113
120
1
1
1
1
1
xECcCtCetoaorovdseswxsige ru
Figure 14.4 Sample of the printout produced by the Oric Manual’s ‘PRINTER
TEST’ program
Printers and hard copy 123
1@ REM ORIC-I PRINTER CHARACTER SET
5@ CALLHE6CA
6@ LPRINTCHR$(18)5"C1"
30 LPRINT"A"
10@ LPRINTSPCCS) 5"CHARACTER SET"
118 xX=32
12@ REPEAT
138 REPEAT
140 LPRINTX3CHRSCX) 5"
158 272+] :X=x+1
168 UNTIL2=4
170 2=@
18@ LPRINTCHR$(23)
19@ UNTILX> 127
208 CALL#E8@4 :END
Figure 14.5 (a) ‘ORIC PRINTER CHARACTER SET’ program; (b) Printout of
character set
case C1, which selects blue), whereas in text mode we can only
advance the colour by one or more steps from wherever it happens to
be now.
This raises an important point: all the examples in the printer hand-
book assume that you run them immediately after the printer has
performed its switch-on routine. In practice, it is much safer to begin
any printer program without any such assumption; this allows for
previous use to have left the printer in, say, graphics mode, with any
one of the four pen colours selected. Now having switched to
graphics mode so that we can select a specific pen colour in line 60,
line 90 — LPRINT’‘A’”’ — switches back to text mode, moves the pen
to the left-hand column and defines this position as the ‘origin’ for
further printing, a useful command. My first attempt had these two
lines telescoped into one, thus:
60 LPRINT CHR$(18);“C1"; “A”
but for some reason this does not work; the “A” is simply ignored.
Hence it now appears separately as line 90.
Line 100 prints ‘CHARACTER SET’, nicely centred with SPC(9) —
you will recall, from Chapter 3, that on early models of Oric, the TAB
command doesn’t work. The rest of the program prints out each of
the printable characters (codes 32—127 inclusive) preceded by the
124 Printers and hard copy
appropriate number. The printout is arranged as four characters per
line with each line in a different colour. CHR$(29) in line 180 rotates
the penholder one step, thus cycling through the four available
colours in the order blue, green, red, black. As there is no semicolon
at the end of line 180, it also causes the printer to start a new line.
Finally (line 200) the program calls the routine to restore keyboard
interrupts, which is located at #E804. If this were not done, the
keyboard would be without control over the machine. It would then
be necessary to press the RESET button to restore control to the
keyboard.
Inevitably, when you write printer routines you will find yourself
typing LPRINT many many times. Unfortunately, although one can
use ‘2’ instead of ‘PRINT’, the abbreviation L? is not accepted by the
machine.
With the aid of frequent reference to the printer manual, text mode
had not proved too difficult to master, so it was time to move on to the
graphics mode. | thought a spiral would be a nice shape to draw and
a program to do this was quickly written. Unfortunately, it didn’t
work. It turned out that the graphics DRAW commands would only
accept negative values of the X and Y parameters, which was dis-
tinctly limiting. The same problem was found with the 36-armed star
in the printer manual’s Appendix A Sample Programs.
| then obtained a printer demonstration cassette from Tansoft and,
whereas | couldn’t draw the 36-pointed star, this program could. So |
LLISTED the program out on the printer; it is just six feet long. Right at
the end of the printout was a subroutine not found in the printer
manual’s sample programs, and this was the secret of success.
It appears that when Oric sends a numeric variable to the printer as
a parameter, it is preceded by a control character. If the value of the
variable is a negative number, the control character is converted to a
negative sign and all is well. In the case of a positive number, the
control character must be stripped off, as the printer does not recog-
nise it. If it is left there, the printer assumes a value of zero for the
parameter, instead of the intended positive number. It is thus neces-
sary to send variables to the subroutine (line 7000 in Fig. 14.6) to strip
off the control character if the value is positive, before sending them
to the printer as parameters for DRAW or MOVE commands.
Equipped with this piece of arcane knowledge, | soon had my
spiral program working, and it finished up as in Fig. 14.6. This draws
an-expanding anticlockwise spiral in blue and then changes to red,
continuing in the same direction but spiralling inwards to finish up
back at the centre.
This is but a trivial example of the Oric printer’s plotting ability. It
can do much more useful things, such as plotting graphs — there is
even a command for drawing X and Y axes with regular graduation
Printers and hard copy 125
10 REM BICOLOUR SPIRAL
2@ REM FOR THE ORIC-1 COLOUR PRINTER
8@ CALL#E6CA
98 LPRINTCHR$(18) 5"A"
108 LPRINTCHR$(18)5;"I"
118 LPRINT"M24@, -248"
128 LPRINT"I"
13@ STP=P1710:M=1 :LPRINT"C1"
14@ X=COSCA) :Y=SINCAJ
158 22=INTCL¥X)
151 GOSUB722828
152 X$=22$
155 22=INTCLXY)
156 GOSUB/288
157 Y$=2e$
168 A=AtSTP:L=L+M
178 IFL> 1@@THENM=-1 -LPRINT"C3" :GOTO148
171 IFL<@THENLPRINT"CO" :CALL#E8@4 :END
175 PRINTX;
188 LPRINT"D" 5X$3","Y$
185 PRINTY;
198 GOTO142@
7088 REM ROUTINE TO STRIP OFF CONTROL CH
ARACTERS
7010 22$=STR$( 22) 2 IFLEFTS(22$, 1 3="-"THEN
GOTO07838
7020 22$=RIGHT$(2Z2$,LENC22$)~-1)
7838 RETURN
Figure 14.6 Graphics demonstration routine for the Oric printer, with sample
printout
marks along their lengths at whatever spacing you choose! The axes
can be labelled with printing parallel to each, as the Oric printer can
print horizontally, vertically (with the print facing in either direction),
or even upside-down.
15
Odds and ends
This chapter is a collection of odd points which either don’t fit conve-
niently in any other chapter or which have arisen since the earlier
chapters were written.
The cold start
It was mentioned in Chapter 3 that a cold start could be effected with-
out pulling out the power lead from the back of the machine. If you
wish to interface other equipment to your Oric via the BUS EXPAN-
SION socket, you will need a 34-way IDC (insulation displacement
connector) cable mounting socket, e.g. R.S. Components stock
number 467-302, from any good electrical supplier. You will also
find this item advertised in the more hardware-oriented electronics
magazines such as Practical Electronics, Electronics Today Interna-
tional, Elektor, Hobby Electronics, etc., complete with a length of 34-
way ribbon cable attached.
A normally open circuit push-button (push to make, momentary)
connected between pins 4 and 34 of the BUS EXPANSION socket
will provide you with a cold start facility, i.e. one which RESETS the
machine completely, wipes all the RAM memory clean with a RAM
test routine and displays the start-up message as described in Chapter
2. Just occasionally, my machine fails to auto reset at switch-on,
displaying a random pattern of bars or bands idefinitely. A press on
the RESET button between pins 3 and 34 works infallibly and is more
convenient and reliable than disconnecting the supply lead at the
back of the Oric or switching off the mains at the wall socket.
126
Odds and ends 127
Flowchart symbols
Next, a word about flowcharts. We saw some in Chapter 3, and Fig.
15.1 shows the various symbols which are commonly used, together
with their meanings. Unfortunately, there are minor differences in
usage, but the meaning is usually clear.
Start
(or end) Operation
False
Decision
To same numbered
bubble on another
(or same) sheet of
flowchart
Output to printer
Predefined process, Multiple decision,
eg subroutine eg computed goto
These symbols are generally in conformance with ANSI Standard
‘Standard flowchart symbols and their use in information processing; (X 3.5)’
Figure 15.1 American National Standards Institute (ANSI) flowchart symbols
128 Odds and ends
The snowflake problem
Talking of Chapter 3, did you work out the average percentage of
snowflakes after the program has been running a long time? It is a
simple problem in probability theory. Oric is capable of working out
quite complex probability calculations, once suitably programmed.
There is no space here to go into probability theory, but the solution
to the snowflake problem falls out in a few lines of algebra.
Mathematically defined, probability ranges from 1 for a certainty to
zero for an impossibility, with 0.5 representing, for example, the
probability of a tossed coin landing ‘heads’. Let the probability that
any given square contains a snowflake (after the program has been
running for a long time) be S. Then, referring to Fig. 3.1, let the
probability that a square contains a snowflake after the next time
round the program loop be S’. At the first decision box, if the square
called up by the random address selector contains a blank (prob-
ability 1—S), a snowflake will certainly (probability 1) be printed
there. If on the other hand it contains a snowflake (probability S), then
there is a probability of 0.8 that it won’t be thawed (second decision
box). Thus
S’=(1-S)x1+S x08
or S'’=1-—-S+0.8S =1—-—0.2S
But if the program has been running long enough to settle to a
constant percentage of displayed snowflakes, the probability that a
given square contains a snowflake before going round the loop must
be the same as afterwards, i.e. S = S’. But
S’=1-0.2S so
S =1-0.2S also
Adding 0.2S to both sides gives
1.28 =1
and dividing both sides by 1.2 gives
S = 1/1.2 = 0.83
So on average 83.3% of squares will eventually contain a snowflake.
Odds and ends 129
A software bug
Most machines have at least one software ‘funny’, and the Oric is no
exception. As time goes on they are ironed out, one by one, by
modifications to the routines stored in the machine’s ROM. Here is a
typical oddity of the version of BASIC in my machine — is yours the
same?
5 REM TYPICAL SOFTWARE BUG DEMO
10 A=0:B=1
20 A$ = “A<B”:B$ = “A>=B”
30 IFA<B THEN PRINT “A<B” ELSE PRINT “A>=B”
40 END
130 IF A<B THEN PRINT “A<B” ELSE PRINT B$
230 IF A<B THEN PRINT A$ ELSE PRINT B$
This program (lines 5—40) will run correctly as it is, returning
A<B or
A>=B
if you change line 10 to set A = 2, say.
Likewise, all is well if you change the text of line 30 to that shown in
line 130. But if you change line 30 as shown in line 230, life gets more
problematical. In this case, all is well if, in line 10, B is set less than A;
but if not, strange things happen to the display! (Set B = 10000 and
try various values of A. A RESET will restore things to normal.)
There is an unfortunate sequel to the printer software bug
mentioned in Chapter 14. You will recall that it is necessary to turn off
the keyboard interrupt routine while printing, to avoid the output of
spurious characters, and to turn it on again afterwards. This is fine for
all types of printing and plotting except program listings. These are
printed out using the command LLIST, but this command (like LIST),
whether called from the keyboard or from within a program, termi-
nates by returning command to the keyboard. Program execution is
terminated and subsequent instructions — including any call to
#E804 — are ignored. The keyboard routine is therefore not
re-enabled; the machine has effectively crashed. There seems to be
no way round this problem at present, and one must therefore RESET
at the end of program printout using LLIST.
Tips for the machine code programmer
First a snippet which refers to Chapter 13. We mentioned there
Interrupt Requests (IRQ) and Jumps to Subroutines (JSR). Figure 15.2
130
[AOR [ADL [Mnemonic [Op cove
Odds and ends
Low memory
— SP after IRQ or NMI
but before RTI
SP before |RQ or NMI
and after RT!
PC at time of IRQ or
NMI; this instruction
will complete before
interrupt is serviced
PC after RTI
Interrupt service
main body
Return from
interrupt
} NMI vector
} RES vector
} IRQ vector
High memory
——SP after JSR but before
return (RTS)
SP before JSR and after
return (RTS) from
subroutine
Jump to subroutine
Return from subroutine to
this location
Subroutine main
body
Return from subroutine
High memory
Figure 15.2 Operation of (a) IRQ (NMI, BRK similar) and RTI; (b) JSR and RTS
Odds and ends 131
illustrates how these and related commands operate. Thus an IRQ
will cause the processor to jump to an address whose location in
memory it finds stored in ROM at #FF FE, #FF FF (low, high). In a
dedicated application, such as a process controller, the address
jumped to would probably be the IRQ routine itself. In a general
purpose machine, the address jumped to is likely to be in RAM and
would itself initiate a further JSR to an IRQ routine in ROM, RAM or
PROM. The RAM address jumped to would be loaded with the final
IRQ routine address during the switch-on initialisation routine.
Thus the user has the option of changing what happens when an
IRQ occurs, by changing the ‘vector’ in the RAM location to point toa
new IRQ subroutine located somewhere else. This would result in a
further JSR loop in Fig. 15.3(a) before finally reaching the main body
of the IRQ service routine, via the vector held in RAM.
And still on machine code, there is an inconsistency in the Oric
manual of which you should beware if you have tackled Chapter 13.
Fig.13.1 is a table of 6502 instruction codes. Now an instruction such
as LDA can be ‘immediate’, so that op-code A9 means ‘LoaD the
Accumulator with the number immediately following this op-code’.
Thus A9#FF would load the number #FF (255 in decimal) into the
accumulator.
In mnemonic code, as used by an assembler program, this would
appear as LDA #FF, where the # indicates not that the following
number is in hex, but that the preceding op-code should be taken as
‘immediate’. Most computer manuals use $ to indicate a hex
number, e.g. $FF, and there is thus no confusion since A9FF would
appear in mnemonic code as LDA #$FF. | haven’t been able to get
hold of the Tansoft Assembler/Disassembler/Monitor for the Oric 1,
so | don’t know how it handles this problem.
The program that won’t load
You may sometimes be faced with trying to rescue a program which
won't load properly; for example a friend may have CSAVEd it on
cassette for you on his recorder. The characteristics of cassette
recorders do vary considerably from one make to another, so the
obvious solution is to borrow the friend’s machine, load the program
into Oric and then save it on your own recorder. However, if this is
not possible, you may still be able to rescue the program, if you know
how. Here’s how to go about it.
First, load the program; don’t run it, but list it on the screen. If it is
completely garbled, this is the point to give up. If it looks sensible,
then run it. If it hangs up with an error message, then you have a guide
as to which line it goes wrong at. Chapter 13 explained how BASIC
132 Odds and ends
terms in a program line are stored as tokens, and if one of these gets
corrupted the error may be fairly obvious; for example
210 FOR N = 0 RESTORE 12 STEP 3
The error may be more subtle, such as variable name A getting
corrupted to B, or there may be number of possibilities; for example
560 IF A DATA INT(B f 2 + RND(1)*C)THEN GOSUB1000
Here ‘DATA’ is obviously wrong, but should it be ‘>’, ‘=’ or ‘<’? In
these cases a printer comes in very handy, though listing on the
screen can serve. The trick is to LLIST the program to the printer, then
reload the program afresh and print it out (or LIST it) again. With luck
you won't get the same errors in both versions and when the program
in the computer hangs up, you can compare the offending line
number with the version in the other listing.
Each time you chase out an error, don’t forget to save the latest
version on cassette and also to mark up your listings. This way, if a
later error causes an irrecoverable crash, you won't have wasted any
of your earlier efforts at correcting the program. If you are finding it
difficult to pin down a particular error, don’t forget the techniques
using END, STOP, TRON and TROFF, described in Chapter 5.
While on the subject of the operation of BASIC, there is a point
about the command GOSUB which you may not have realised. One
tends to think that the corresponding RETURN results in operation
continuing at the line following the line containing the GOSUB.
Actually, this is only the case if the command ‘GOSUB (Line number)’
stands last in its program line. In fact, RETURN continues with the
command following the GOSUB, even if it is in the same line, as the
following little program demonstrates.
5 REM *** GOSUB DEMO ***
10 | =0:REPEAT
20 PRINT CHR$(65 + 1); “=’";:GOSUB 100: |=1+1:UNTILI=5
30 END
100 PRINT 65 + I,
110 RETURN
Disk drives and available RAM
Have you heard about the ‘white machine’? This in-phrase refers to a
machine with lots and lots of RAM, say 64K or 128K or more, and
very little else. That sounds pretty limiting, but the point is that being
Odds and ends 133
unencumbered with lots of ROM, the machine is ideal for use in
conjunction with a disk drive. The machine is loaded from disk with
the necessary DOS (disk operating system) and also with whatever
language it is desired to use. This could be BASIC or it could alterna-
tively be a more sophisticated high-level language such as Pascal or
FORTH or whatever. Alternatively, in the other direction, one
could load instead an Assembler/Disassembler/Monitor and turn the
machine into an MDS (microprocessor development system).
Now, as | write this, a disk system for the Oric is still in the future,
but it is interesting to note that the BUS EXPANSION socket includes a
pin labelled ROMDIS. The purpose of this is not covered in the Oric
Manual, but it disables the ROM which normally occupies the final
16K of the machine’s 64K addressing range. The 48K Oric actually
contains 64K of RAM, and once the ROM is disabled the whole of this
becomes available. Thus in some respects the Oric is itself a white
machine, and in due course high-level languages other than BASIC
will become available to the Oric owner who has the necessary Oric
disk drive.
Appendix 1
Oric 1 memory map
Decimal
| (48K machine)
hi H Hi 6K hi
USI ae HIRES mode |" ™ Jee
FFFF 65535 FFFF
49152 cooo 49152 cooo
16352|__ Spare IBFEQ 649120 ~—sBFEO
BB80
ne
47104 B800 char set 14336
Standard
ban 1090 _oroof asst Iisse
available for User programs
tuser programs (if‘grab’ command
yuniess ‘grab’
8192 A000;command is issued;
Alternate 409601 ‘release’ command
7168 char set i9coolallows HIRES
Standard 39936} mode to use area
6144 char set Spool eooos Sess os etaP eases. cotsceced
User programs }38912 User programs
/\/\/ \/\
Page 4 (up to 420
for m/c programs,
Page 3 (physica
1/O addresses)
variables
Page 1 (stack)
Page 0 (allocated) O10 «256
0000 0
Both modes Hex — Decimal
0500 1280
0400 1024
0300 768
0200 512
134
Appendix 2
Attributes
This table shows the functions assigned to control codes 0 to 31 when
sending information to the screen of a TV or monitor.
0 black @ black P
1 red A red Q
2 green B green R
3 yellow Cc yellow Ss
4 blue D blue T
5 magenta E magenta U
6 cyan F cyan Vv
7 white G white Ww
8 SH/ST STD H TEXT 60Hz X ] 50 Hz appicable in UK
9 SH/ST ALT \ TEXT 60Hz Y | £0 He sepiicable tn 18
DH/ST STD J TEXT 50Hz Z_ | temporary loss of screen
DH/ST ALT K TEXT 50Hz {_ | synchronisation
SH/FL STD L GRA 60Hz \
SH/FL ALT M GRA 60Hz }
DH/FL STD N GRA 50Hz ~
DH/FL ALT fe) GRA 50Hz
Le Escape character ———J
SH = _ single height
DH = double height
ST = steady
FL= flash
GRA = dot graphics
STD = standard character set
ALT = user character set
135
Appendix 3
ASCII code
ASCII stands for American Standard Code for Information Inter-
change. As.can be seen, it is a seven-bit code.
A BASIC program, stored within Oric, uses codes 128—255 (bit 7
set to 1) as ‘tokens’ to indicate BASIC keywords such as ‘GOTO’,
‘DATA’, ‘=’, etc. When operating with a printer, Oric uses some of
the control characters, codes 0 to 32, e.g. 10 = LINE FEED, 17 =
SELECT TEXT MODE, 29 = NEXT PEN COLOUR, etc. However,
when sending information to TV or monitor screen, Oric redefines
the control codes as ‘attributes’, as shown in Appendix 2.
ASCII conversion table
=| SB BUBB OONDUAWNHHO
OZZT-“AT-T-LTOA™MMOAVFO@
HoT TW TNX KSKCAYAHDV
©
a
b
c
d
e
f
8
h
i
j
k
|
m
n
oO
TAMNONDSFORNDUBWN-O
O’~mTaNX xX SEK OTH AOD
e.g.A=1+64=65
136
Appendix 3 137
The ASCII symbols
NUL Null DLE DataLink Escape
SOH Start of Heading DC Device Control
STX Start of Test NAK_ Negative Acknowledge
ETX EndofTest SYN Synchronous Idle
EOT Endof Transmission ETB —_Endof Transmission Block
ENQ_ Enquiry CAN Cancel
ACK Acknowledge EM — Endof Medium
BEL Bell SUB Substitute
BS Backspace ESC Escape
HT — Horizontal Tabulation FS File Separator
LF Line Feed GS Group Separator
VT _ Vertical Tabulation RS Record Separator
FF Form Feed US Unit Separator
CR Carriage Return SP Space (Blank)
SO _ ShiftOut DEL Delete
SI Shift In
Appendix 4
Centronics interface
The following information may be useful if you wish to interface Oric
to a dot matrix printer with a full Centronics interface. The Oric uses a
subset of the connections listed below, with different pin numbering.
An Apple or Dragon compatible printer lead has a 20-pin plug at one
end, which will mate with the Oric’s printer socket, and a 36-way
Amphenol plug at the other, which will mate with the Centronics
parallel interface on most dot matrix printers. This type of lead can be
obtained from Watford Electronics, 34/35 Cardiff Road, Watford,
Herts., or many advertisers in the various magazines devoted to
personal computing.
A typical dot matrix printer cannot plot and draw lines like the Oric
printer, but on the other hand it can handle paper up to 10 inches
wide and has a variety of print styles with 40, 66, 80 or 132 characters
per line and a printing speed of around 80 characters per second, as
against the Oric printer’s 12 characters per second.
The Centronics interface transmits data in byte-wide bit-parallel
form. The table shows the particular implementation of the
Centronics interface used by a typical dot matrix printer. The pin
numbers refer to the pins of an Amphenol connector type 57-30360.
Signal Return Signal Direction Description
pinno. pinno.
1 19 STROBE In STROBE pulse to read
data in. Pulse width must
be more than 0.5 ps at
receiving terminal.
The signal level is
normally ‘high’; read-in of
data is performed at the
‘low’ level of this signal.
138
Appendix 4 139
Signal Return —_ Signal Direction Description
pinno. _pinno.
2 20 DATA 1 In These signals represent .
3 21 DATA 2 In information of the 1st to
4 22 DATA 3 In 8th bits of parallel data
5 23 DATA4 In respectively. Each signal
6 24 DATA5 In is at ‘high’ level when data
7 25 DATA6 In is logical ‘I’ and ‘low’ when
8 26 DATA7 In logical ‘0’.
9 27 DATA8 In
10 28 ACKNLG Out Approx. 5 us pulse.
‘Low’ indicates that data
Has been received and that
the printer is ready to accept
other data.
11 29 BUSY Out A ‘high’ signal indicates
that the printer cannot
receive data. The signal
becomes ‘high’ in the
following cases:
1. During data entry.
2. During printing operation.
3. In off-line state.
4. During printer error
status.
12 30 PE Out A ‘high’ signal indicates
that the printer is out
of paper.
13 — SLCT Out This signal indicates that
the printer is in the
selected state.
14 — AUTO In With this signal being at
FEED XT ‘low’ level, the paper is
automatically fed one line
after printing.
(The signal level can be
fixed to ‘low’ with DIP SW
pin 2-3 provided on the
control circuit board.)
15 _ NC Not used.
16 = OV Logic GND level.
17 — CHASSIS-GND — Printer chassis GND.
In the printer, the chassis
GND and the logic GND are
isolated from each other.
18 _ NC — Not used.
19to _— GND — TWISTED-PAIR
30 —— RETURN signal GND level.
31 —_ INIT In When the level of this signal
becomes ‘low’, the printer
controller is reset to its
initial state and the print
buffer is cleared. This signal
140
Signal
pinno.
Appendix 4
Return Signal
pin no.
Direction
Description
32
33
34
35
36
ERROR
— GND
_ NC
— SLCTIN
Out
is normally at ‘high’ level,
and its pulse width must be
more than 50 us at the
receiving terminal.
The level of this signal
becomes ‘low’ when the
printer is in:
1. Paper end state.
2. Off-line state.
3. Error state.
Same as with pin nos. 19
to 30.
Not used.
Pulled up to +5 V through
4.7 kQ resistance.
Data entry to the printer
is possible only when the
level of this signal is ‘low’.
(Internal fixing can be
carried out with DIP SW 1-8.
The condition at the time
of shipmentis set ‘low’
for this signal.)
Notes:
1. ‘Direction’ refers to the direction of signal flow as viewed from the printer.
2. ‘Return’ denotes ‘TWISTED PAIR RETURN’ and is to be connected at signal
ground level. As to the wiring for the interface, be sure to use a twisted-pair
cable for each signal and never fail to complete connection on the Return
side. To prevent noise effectively, these cables should be shielded and
connected to the chassis of the host computer and the printer, respectively.
3. All interface conditions are based on TTL level. Both the rise and. fall times of
each signal must be less than 0.2 ys.
4. Data transfer must not be carried out by ignoring the ACKNLG or BUSY
signal. (Data transfer to this printer can be carried out only after confirming
the ACKNLG signal or when the level of the BUSY signal is ‘Low’.)
Appendix 4 141
BUSY
ACKNLG
0.5ys (min)
Approx. 5ps
DATA
STROBE
0.5ys (min)
0.5ys (min)
Appendix 5
Text screen map
48000
etc
Reserved column (for background colour); 48039
may not be used in TEXT or LORES 48079
etc
48042
48041
etc
Warning: in TEXT mode this is reserved for
foreground colour;
may be used in both LORES modes
Y co-ordinates
‘ 38
X co-ordinates
Example: PLOT 1,3,‘A” plots an A as shown. Alternatively Poke 48162,65 does exactly the same.
Screen map: TEXT, LORES 0 and LORES 1 modes
POKEing provides access to amy space.You could, for example, change ‘CAPS’ in 48036—48039
to ‘CAPITALS’ in 48032—48039
The TEXT screen is normally addressed with “PRINT”
The LORES screen is normally addressed with “PLOT”
Either may be POKEd into directly
142
Appendix 6
High-resolution
screen map
40961
—
Bit 543210
40960
——
Bit 543210
ave HOUUUTTTLIT
of 41000 Goce —_——$ 9
Screen map for HIRES mode
The HIRES screen, usually addressed with CURSET, DRAW, FILL, CHAR, etc, may also be
POKEd into directly. For example, to set POINT 0,1 (bit 5 of 41000) to foreground colour,
use POKE 41000,96 (bit 5 = 25 = 32, bit 6 set 1 denotes foreground; 64 + 32 = 96)
143
Appendix 7
Oric software suppliers
The information provided below is believed to be correct at the time
of writing. This list does not claim to be exhaustive even at the date of
preparation, and many different suppliers will doubtless appear in
future. The author has not evaluated the software offered for sale by
any firm listed, and such a listing is not a recommendation to buy
from that source nor is the omission of a supplier a recommendation
not to buy from that source.
Tansoft Ltd 3 Club Mews, Ely, Cambs. CB7 4NW.
(GM BP CS) Tel. (0353) 2271
Durell Software = Higher Combe, Combe Florey, Taunton,
(GMCS) Somerset TA4 3)F.
Crunch Computer 76 Victoria Road, Swindon, Wilts.
Systems Ltd
(CS)
Firefly Software —_8 Poolsford Road, London NW9 6HP.
(GM BP CS)
IK SoftwareLtd 9 King Street, Blackpool, Lancs.
(GM) Tel. (0253) 21555.
PSS 452 Stoney Stanton Road, Coventry
(GMCS) CV6 5DG. Tel. (0203) 667556.
Arcadia Software Freepost, Swansea SA3 4ZZ.
(GM)
144
Appendix 7
145
Williams 1 Dunblane Close, Garswood, Ashton in
(GM BP) Makerfield, Lancs WN4 OSH.
Taskset Ltd 51-53 High Street, Bridlington, YO16 4PR.
(GM) Tel. (0262) 602668 (24 hours).
GM= Games
BP= __ Business programs: accounts, word processing, mailing
lists, etc.
CS= Computer software: assembler/disassemblers, high-level
languages (e.g. FORTH, Pascal, etc.), compilers etc.
Abacus, 1, 2
Accumulator, 98ff
Address bus, 7, 110
ALU, 59, 110
AND gates, 55
Animation, 72
Arithmetic and logic unit, see ALU
Array, 22
ASCII, 19, 136
Assembler, 94ff
Attack, 78
Attributes, 66, 68, 70, 135
BASIC, 14, 42
BCD, 52ff, 100
Binary coded decimal, see BCD
Binary numbers, 51 ff
Bits, 6, 9,51, 9Off
Boolean algebra, 54ff, 90ff
Borrow, 52ff
Byte, 9, 10, 52, 69, 98, 102, 106
Carry, 52ff
Cold start, 13, 126
Commutative law, 42
Compound interest, 47
CONTROL C, 13
Data bus, 7, 110
Debugging, 39
Decay, 79
Decimal numbers, 51
Editing, 36ff
Envelope, 77ff
EPROM, 108
Erasable programmable read only
memory, see EPROM
Exclusive OR gate, see EXOR gate
EXOR gate, 56
Exponential function, 47
Flag, 22
Flags register, see Processor status
register
Flowcharts, 18ff, 86
Gates, 55ff
Grads, 50
Graphics, 26ff, 65ff, 118, 121
Hex, 9, 52ff
Hexadecimal, see Hex
IC, 3, 6, 65
Index, 44
Index registers, 105, 110
Indices, see Index
Integrated circuit, see IC
Interrupts, 108, 109
Inverse colours, 61, 70, 71, 73
Irrational numbers, 42, 43
Large scale integration, see LSI
Logarithms, 48
LSI, 3
Machine code, 5, 94ff
Masking, 59, 113
Medium scale integration, see MSI
Merging programs, 85
Monitor, 6, 65
147
148
Index
Most significant bit, see MSB
MSB, 52
MSI, 3
Music, 75ff
Napierian logarithms, 48
Natural logarithms, 48
Numeric variable, 15, 124
Op codes, 94ff
Operation codes, see Op codes
OR gates, 55
Pi, 16, 42, 43
Pixels, 68
Portability, 89
Powers, 44
Processor status register, 99, 111, 113,
114
Progressions, 46
Radians, 49
RAM, 6, 66, 115, 132
Random access memory, see RAM
Read only memory, see ROM
Real-time process, 65
Recurring numbers, 43
RESET, 12, 13, 100, 118, 124, 126, 129
ROM, 6, 66, 132
Serial attributes, see Attributes
Series, 46
Sorting, 62
Sound, 75ff
Square roots, 45
Stack, 108
Status register, see Processor status
register
String variable, 15, 22, 60ff
Structured programming, 86
Surds, 43
Tabulation, 62
Teletext graphics, 66
Transistor, 1
Trigonometry, 48
Two’s complement, 53, 54, 92, 114
Variables, 15, 45
VDU, 6, 22, 65
Visual display unit, see VDU
Warm start, 13
Computing with the Oric 1
Computing with the Oric 1 has been written for the owner
or potential owner of the Oric 1 micro. It assumes no previous
enrol i(ex0(6(= me) mere)any olU] (are mela elcere|e-laalanliare Par-lale mse 11M ole)
particular interest to the first-time user. The book
complements the Oric Manual and is intended to be-used
alongside it.
7 Nam lalixeye [lei (o)amsy-101(e]amere) =16-m cal -mlall Ue) Ui ealiale pela Lule:
setting-up of the micro, followed by some simple BASIC
'o}coyele-Vanlanliale pm r= lCcimevar-\e) (cie-Mlal (cole lU(er-manle)e-m-leN7-lalei-re|
isYate)| Ommal(e]abic=s-1e) [6] celamere)(el0lmee-lelale mm lal evolu arom (cr-l(lece
FeVavo mal (clar-(ellare mm Yi (alr- Wj ol-1e1f-lmy=161 ((e)a mean a(-m ©) elon olgialccim-lare|
EValo)iat=1melamaar-(oaliarsmerele(-u o)celele-lanlanliace Myawalelanlel-ime)melsie late
programs are included.
aM alismicw- Wm ole- (ener 1m olere) mu alevam 71 |mal=1) om ele me (=) mcal-mel-1-)mice)an)
your Oric 1.
ISBN 0 408 01444 X
_________ Newnes Microcomputer Books
mlentaatela
Solan ole iiareh ishin-2@yi (ed
N